设计模式之命令模式实现方法示例分析(Brief Introduction)
命令模式(Command Pattern)将请求封装为一个对象,从而使你用不同的请求对客户进行参数化,对请求排队或纪录请求日志,以及支持可撤销的操作。
Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations
二、解决的问题(What To Solve)
当需要有撤销或者恢复操作时,可以考虑使用命令模式。
三、命令模式分析(Analysis)
1、命令模式结构

Command抽象类:声明一个接口,用于执行操作,declares an interface for executing an operation。
ConcreteCommand实现类:将一个接收者对象绑定到一个动作。调用接收者相应的操作,以实现Execute 。
defines a binding between a Receiver object and an action
implements Execute by invoking the corresponding operation(s) on Receiver。
Receiver类:知道如何执行一个请求相关的操作。knows how to perform the operations associated with carrying out the request.
Invoker类:要求命令执行一个请求。asks the command to carry out the request 。
2、源代码
1、Command抽象类:声明一个接口,用于执行操作
abstract class Command
{
protected Receiver receiver;
public Command(Receiver receiver)
{
this.receiver = receiver;
}
public abstract void Execute();
}
2、ConcreteCommand具体实现类:将一个接收者对象绑定到一个动作
class ConcreteCommand : Command
{
// Constructor
public ConcreteCommand(Receiver receiver)
:base(receiver)
{
}
public override void Execute()
{
receiver.Action();
}
}
3、Receiver类:知道如何执行一个请求相关的操作
class Receiver
{
public void Action()
{
Console.WriteLine("Called Receiver.Action()");
}
}
4、Invoker类:要求命令执行一个请求
class Invoker
{
private Command _command;
public void SetCommand(Command command)
{
this._command = command;
}
public void ExecuteCommand()
{
_command.Execute();
}
}
4、客户端代码
static void Main(string[] args)
{
// Create receiver, command, and invoker
Receiver receiver = new Receiver();
Command command = new ConcreteCommand(receiver);
Invoker invoker = new Invoker();
// Set and execute command
invoker.SetCommand(command);
invoker.ExecuteCommand();
Console.ReadKey();
}
3、程序运行结果
四.案例分析(Example)
1、场景
使用命令模式进行计算器计算,可以是加减乘除等运算,可以进行Undo操作和Rodo操作。如下图所示

Command抽象命令类:声明一个接口,用于执行操作。
CalculatorCommand具体实现类:将一个接收者对象绑定到一个动作。调用接收者相应的操作,以实现Execute 。
UnExecute方法:执行Undo操作。
Calculator 类-Operation方法:执行加减乘除操作。
User类:要求命令Calculator执行一个计算请求。
Compute方法:加减乘除等计算操作
Undo方法:撤销操作。Redo方法:重复操作。
2、代码
1、抽象命令类Command及其计算器类CalculatorCommand
/// <summary>
/// The 'Command' abstract class
/// </summary>
abstract class Command
{
public abstract void Execute();
public abstract void UnExecute();
}
/// <summary>
/// The 'ConcreteCommand' class
/// </summary>
class CalculatorCommand : Command
{
private char _operator;
private int _operand;
private Calculator _calculator;
// Constructor
public CalculatorCommand(Calculator calculator,char @operator, int operand)
{
this._calculator = calculator;
this._operator = @operator;
this._operand = operand;
}
// Gets operator
public char Operator
{
set { _operator = value; }
}
// Get operand
public int Operand
{
set { _operand = value; }
}
// Execute new command
public override void Execute()
{
_calculator.Operation(_operator, _operand);
}
// Unexecute last command
public override void UnExecute()
{
_calculator.Operation(Undo(_operator), _operand);
}
// Returns opposite operator for given operator
private char Undo(char @operator)
{
switch (@operator)
{
case '+': return '-';
case '-': return '+';
case '*': return '/';
case '/': return '*';
default: throw new
ArgumentException("@operator");
}
}
}
2、计算器类Calculator
/// <summary>
/// The 'Receiver' class
/// </summary>
class Calculator
{
private int _curr = 0;
public void Operation(char @operator, int operand)
{
switch (@operator)
{
case '+': _curr += operand; break;
case '-': _curr -= operand; break;
case '*': _curr *= operand; break;
case '/': _curr /= operand; break;
}
Console.WriteLine(
"Current value = {0,3} (following {1} {2})",
_curr, @operator, operand);
}
}
3、请求类User
/// <summary>
/// The 'Invoker' class
/// </summary>
class User
{
// Initializers
private Calculator _calculator = new Calculator();
private List<Command> _commands = new List<Command>();
private int _current = 0;
public void Redo(int levels)
{
Console.WriteLine("\n---- Redo {0} levels ", levels);
// Perform redo operations
for (int i = 0; i < levels; i++)
{
if (_current < _commands.Count - 1)
{
Command command = _commands[_current++];
command.Execute();
}
}
}
public void Undo(int levels)
{
Console.WriteLine("\n---- Undo {0} levels ", levels);
// Perform undo operations
for (int i = 0; i < levels; i++)
{
if (_current > 0)
{
Command command = _commands[--_current] as Command;
command.UnExecute();
}
}
}
public void Compute(char @operator, int operand)
{
// Create command operation and execute it
Command command = new CalculatorCommand(
_calculator, @operator, operand);
command.Execute();
// Add command to undo list
_commands.Add(command);
_current++;
}
4、客户端代码
static void Main(string[] args)
{
// Create user and let her compute
User user = new User();
// User presses calculator buttons
user.Compute('+', 100);
user.Compute('-', 50);
user.Compute('*', 10);
user.Compute('/', 2);
// Undo 4 commands
user.Undo(4);
// Redo 3 commands
user.Redo(3);
Console.ReadKey();
}
3、程序运行结果

五、总结(Summary)
命令模式(Command Pattern)将请求封装为一个对象,从而使你用不同的请求对客户进行参数化,对请求排队或纪录请求日志,以及支持可撤销的操作。当需要有撤销或者恢复操作时,可以考虑使用命令模式。
版权
作者:灵动生活
出处:http://www.cnblogs.com/ywqu
如果你认为此文章有用,请点击底端的【推荐】让其他人也了解此文章
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
本站所有文章欢迎任何形式的转载,但请注明作者及出处,尊重他人劳动成果!
文章转载自:中国研发网 [http://www.yanfaw.com]
本文标题:设计模式之命令模式实现方法示例分析(Brief Introduction)
文章转载自:中国研发网 [http://www.yanfaw.com]
本文标题:设计模式之命令模式实现方法示例分析(Brief Introduction)










