【行为型】Command模式

    命令模式是指将用户的请求封装成(命令)对象,从而可将用户不同的请求进行参数化、对这些请求排序或记录请求日志、以及支持回滚恢复操作。记得以前刚开始使用Photoshop时,就发现它的操作历史记录面板特别好用,现在想想,其实也可以通过命令模式来设计。命令模式主要是将请求抽象成对象,以此作为中间的一个中转站,转达请求命令,从而将请求方与响应方解耦。在逻辑层面上,用户只需要发布自己的命令即可,至于由什么样的响应者来处理,则需要看具体下达的是什么样的命令。模式类结构图参考如下:

    模式编码结构参考如下:

 1 namespace command
 2 {
 3     class Receiver
 4     {
 5     public:
 6         void doAction() {/*some code here........*/}
 7 
 8     };
 9 
10     class ICommand
11     {
12     public:
13         virtual void action() = 0;
14         // some code here........
15 
16     };
17 
18     class ConcreteCommand : public ICommand
19     {
20     public:
21         virtual void action() {
22             // some code here........
23             _receiver->doAction();
24         }
25         
26     private:
27         Receiver* _receiver;
28 
29     };//class ConcreteCommand
30 
31     class Invoker
32     {
33     public:
34         void call() {
35             // some code here........
36             // this is a test case below.
37             auto pCommand = new (std::nothrow) ConcreteCommand();
38             pCommand->action();
39         }
40 
41     };
42 
43 }//namespace command
Command模式编码结构参考

     既然命令对象的职责相当于是一个中转站转达请求,则命令模式重点在于命令对象的设计。试想下,如果一个请求需要被多个响应者响应,则只需要简简单单设计一个“复合命令”对象即可。参考如下:

 1 class MacroCommand
 2 {
 3 public:
 4     // some code here........
 5     virtual void execute() override {
 6         // call execute action of all children command object
 7         // some code here........
 8     }
 9     
10 private:
11     typedef std::list<ICommand*> TCmdList;
12     
13     TCmdList    m_listCmds;
14     
15 };//class MacroCommand
复合命令编码参考

    对于命令对象的设计,最复杂的情况是直接将响应者的逻辑直接在命令对象中封装起来,此时就相当于没有使用命令模式的情形,这是一种完全退化的情况。最简单的情况是将请求转抛给具体的响应者,此时命令对象就仅仅只是一个桥梁,起到的作用是将请求方与响应方解耦合。因此,关于命令对象的封装会有个度的评估,此需要看具体设计、项目实际需要、以及当时的上下文环境而斟酌。

posted @ 2016-06-06 09:27  Jacc.Kim  阅读(179)  评论(0编辑  收藏  举报