当初初识Command,我真的不知道它有什么特别之处,看看它的代码:
C#Code
using System;
namespace DoFactory.GangOfFour.Command.Structural
{
// MainApp test applicatio
class MainApp
{
static void Main()
{
// 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();
// Wait for user
Console.Read();
}
}
// "Command"
abstract class Command
{
protected Receiver receiver;
// Constructor
public Command(Receiver receiver)
{
this.receiver = receiver;
}
public abstract void Execute();
}
// "ConcreteCommand"
class ConcreteCommand : Command
{
// Constructor
public ConcreteCommand(Receiver receiver) :
base(receiver)
{
}
public override void Execute()
{
receiver.Action();
}
}
// "Receiver"
class Receiver
{
public void Action()
{
Console.WriteLine("Called Receiver.Action()");
}
}
// "Invoker"
class Invoker
{
private Command command;
public void SetCommand(Command command)
{
this.command = command;
}
public void ExecuteCommand()
{
command.Execute();
}
}
}
有什么特别吗? 注意看客户端,定义了几个对象,调用了几个方法而已,难道简单的对象封装方法就是Command?。还是研究下它的定义吧:
Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
翻译之:
将一个请求包装为一个实体,从而可以使你将不同的请求参数化,对请求排队或记录日志,并且支持Undo操作。
将请求参数化无非就是传递信息。
注意“对请求排队或记录日志”说明什么,说明客户端可以不管命令的结果,也绝不依赖于命令的返回结果,甚至原先的请求发出者可能已经不在了,而命令对象本身仍然是活动的。那么可以这么说,如果客户端虽然调用了对象方法,但是依赖于对象方法的结果才能继续进行,那么就不是Command。注意命令的接受者,或者说实际执行者如何执行命令是与命令的请求者一点关系没有的,接收者如何执行命令甚至与否决命令,都依赖于自己的逻辑判断。OK,现在知道为什么Command也是模式了吧,Command将命令模式把发出命令的责任和执行命令的责任分割开,解除了行为请求者 和 行为实现者之间的耦合。
再来看Undo,Command是要提供Undo的。我觉得这里的Undo绝对不能狭义的理解为程序或事物恢复到执行命令前的状态,Undo的逻辑是你可以自己定义的。我们可以简单的把Undo看作客户端针对上一个请求发出的另外一个请求,至于说逻辑,执行者说了算,至于说执行结果,我并不关心。(这里其实例子不是很好举,不恢复以前状态叫什么Undo呢,可能很多人都会问这个问题。但我认为恢复不恢复以前状态都是执行者的逻辑,命令发起者一点都不关心,从这个角度说,Undo结果这么样都不属于Command模式的问题)
Ok,既然提供了Undo那么请求就可以支持事务了。究竟什么是事务?逻辑不就是“如果你不能给我Do,那么就给我Undo”吗,呵呵
怎么样,现在觉得Command应该不愧于一个模式了吧。不能只看它的表现形式,一定要知道它背后的故事。
不妥之处,高手不吝赐教