1、命令模式(commond),将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
UML图如下:
2、命令模式作用的优点
第一,它能较容易地设计一个命令队列;第二,在需要的情况下,可以较容易地将命令记入日志;第三,允许接收者请求的一方决定是否要否决请求;第四,可以容易地实现对请求的撤销和重做;第五,由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分隔开。
敏捷开发原则告诉我们,不要为代码添加基于猜测的,实际不需要的功能。如果不清楚一个系统是否需要命令模式,一般就不要着急去实现它,事实上,在需要的时候通过重构实现这个模式并不困难,只有在真正需要如撤销/恢复操作等功能时,把原来的代码重构为命令模式才有意义。
3、C++代码实现如下:
- #include <iostream>
- using namespace std;
- /* Receiver类,知道如何实施与执行一个与请求相关的操作
- 任何类都可以作为一个接收者 */
- class Receiver
- {
- public:
- void Action();
- };
- void Receiver::Action() {
- cout << "执行请求" << endl;
- }
- /* command类,用来声明执行操作的接口 */
- class Command
- {
- protected:
- Receiver * p_receiver;
- public:
- Command(Receiver *);
- virtual void Execute() = 0;
- };
- Command::Command(Receiver * p_receiver) {
- Command::p_receiver = p_receiver;
- }
- /* ConcreteCommand类,将一个接收者对象绑定于一个动作
- 调用接收者相应的操作,以实现相应操作,以实现Execute */
- class ConcreteCommand : public Command
- {
- public:
- ConcreteCommand(Receiver *);
- void Execute();
- };
- ConcreteCommand::ConcreteCommand(Receiver * p_receiver) : Command(p_receiver){
- }
- void ConcreteCommand::Execute() {
- p_receiver->Action();
- }
- /* Invoker类,要求该命令执行这个请求 */
- class Invoker
- {
- private:
- Command * p_command;
- public:
- void SetCommand(Command *);
- void ExecuteCommand();
- };
- void Invoker::SetCommand(Command * p_command) {
- Invoker::p_command = p_command;
- }
- void Invoker::ExecuteCommand() {
- p_command->Execute();
- }
- /* 客户端代码,创建一个具体命令对象,并
- 设计它的接收者。 */
- int main()
- {
- Receiver * r = new Receiver();
- Command * c = new ConcreteCommand(r);
- Invoker * i = new Invoker();
- i->SetCommand(c);
- i->ExecuteCommand();
- return 0;
- }