15 行为型模式-----命令模式

模式动机(Command Pattern)将请求封装为对象,从而可以用不同的请求对客户进行参数化;对请求进行排队或记录请求日志;设计可撤销的结构等,这些都是命令模式发挥作用的环境。核心思想是:定义一个抽象的Command接口以执行命令。具体如何执行需要其子类ConcreteCommand来实现。ConcreteCommand在执行命令时必须借助于合适的接受该命令的对象,因此其维护一个Receiver指针。这样就能将命令调用者Invoker和命令的实际接收者Receiver进行解耦,调用者针对抽象Command进行编程,而只有具体Command才与接收者Receiver进行通信。

 

模式结构图:

 

模式代码:

bt_命令模式.h:

 1 #ifndef CP_H
 2 #define CP_H
 3 #include <iostream>
 4 using namespace std;
 5 
 6 /*
 7     抽象命令接口
 8 */
 9 class Command
10 {
11 public:
12     virtual ~Command(){ };
13     virtual void Execute() = 0;
14 };
15 
16 /*
17     具体命令类
18 */
19 class Receiver;
20 class ConcreteCommand : public Command
21 {
22 public:
23     ConcreteCommand(Receiver* rev) : receiver(rev){ }
24     virtual void Execute();
25 private:
26     Receiver* receiver;
27 };
28 
29 /*
30     接收者
31 */
32 class Receiver
33 {
34 public:
35     void Action()
36     {
37         cout << "接收者执行命令..." << endl;
38     }
39 };
40 
41 void ConcreteCommand::Execute()
42 {
43     cout << "启动命令接收者..." << endl;
44     receiver->Action();
45 }
46 
47 /*
48     调用命令者
49 */
50 class Invoker
51 {
52 public:
53     Invoker(Command* cmd) : command(cmd){ }
54     void Invoke()
55     {
56         cout << "发出命令..." << endl;
57         command->Execute();              // 发出执行命令请求
58     }
59 
60 private:
61     Command* command;
62 };
63 
64 #endif // CP_H

 

测试用例.cpp:

 1 #include "bt_命令模式.h"
 2 
 3 int main()
 4 {
 5     cout << "***** 命令模式测试 *****" << endl;
 6 
 7     Receiver* rev = new Receiver;
 8     Command* cmd = new ConcreteCommand(rev);
 9     Invoker* ivk = new Invoker(cmd);
10 
11     ivk->Invoke();
12 
13     delete ivk;
14     delete cmd;
15     delete rev;
16 
17     return 0;
18 }

 

模式分析:

|| 命令模式使得命令的发送者和接收者进行了很好的解耦,因此,新的命令方式可以很容地加入到系统中。结合组合模式可以实现一组命令的执行,相当于具有宏的作用;结合备忘录模式可以实现Undo和Redo操作。

|| 如果一个命令不需要执行Undo操作,也不需要传入参数,那么可以使用模板来实现,这样就避免了为每一个具体命令都创建一个Command子类。

|| 命令模式设计过程中,各个类的协作过程如下:

::Client创建一个具体的ConcreteCommand对象,同时指出其接收者Receiver对象;

::Invoker对象调用Command的Execute操作提交请求命令,若该命令支持Undo操作,那么Concrete在具体执行Execute之前就会存储当前状态以便于撤销该命令时恢复环境;

::ConcreteCommand调用Receiver对象来处理该命令。

 

 

原文地址:https://www.cnblogs.com/benxintuzi/p/4560288.html