命令模式: 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
说白了,就是不去直接指挥别人去干啥干啥,而是记录好你的命令,然后再去指挥对应的人去执行你的任务,由于命令记录好了,那么撤销、排队什么的操作就可行了。
总结下优点: 能较容易的设计一个命令队列。 在需要的情况下,可以较容易的将命令记录日志 允许接收请求的一方决定是否执行请求。 可以容易的实现对请求的撤销和重做。 由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。 把请求一个操作的对象与知道怎么执行一个操作的对象分隔开。
虽然有这么多优点,但是也不是碰到类似情况就一定要实现命令模式。 敏捷开发原则告诉我们,不要为代码添加基于猜测的、实际不需要的功能。如果不清楚一个系统是否需要命令模式,一般不要去着急实现它,事实上,在需要的时候通过重构实现这个模式并不困难,只有在真正需要如撤销/恢复操作等功能是,把原来的代码重构为命令模式才有意义。
书上的图(《大话设计模式》):
使用c++实现它:
#include <iostream> #include <string> using namespace std; class Receiver; //声明执行操作的接口 class Command { protected: Receiver *receiver; public: Command(Receiver *_rec):receiver(_rec) {} virtual ~Command() = 0 {} virtual void Execute() = 0; }; //将一个接收者对象绑定于一个动作,execute调用接收者相应的操作 class ConcreteCommand :public Command { public: ConcreteCommand(Receiver *_rec) :Command(_rec) {} ~ConcreteCommand() {} virtual void Execute(); }; //要求命令执行的类 class Invoker { private: Command* comm; public: Invoker(Command* _com):comm(_com) {} ~Invoker() {} void ExecuteCommand() { comm->Execute(); } }; //实际执行一个请求的类 class Receiver { public: Receiver() {} ~Receiver() {} void Action() { cout << "执行请求" << endl; } }; void ConcreteCommand::Execute() { receiver->Action(); } int main() { Receiver *r = new Receiver(); Command *c = new ConcreteCommand(r); Invoker *i = new Invoker(c); i->ExecuteCommand(); getchar(); return 0; }实际上,Command类把receiver成员换成一个list,然后加上add和del接口,就可以实现一个任务队列,还可以撤销,可以重做,随时添加删除任务,这里就不写了。懒