• 【行为型】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
    复合命令编码参考

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

  • 相关阅读:
    基于python实现自动化办公学习笔记一
    [django]上下文管理器
    [django]中间件
    分布式锁实现
    为什么Redis可以方便地实现分布式锁
    索引字段说明
    COUNT 和 IFNULL函数
    占用空间区别
    java排序算法(七):折半插入排序
    java排序算法(六):直接插入排序
  • 原文地址:https://www.cnblogs.com/tongy0/p/5551840.html
Copyright © 2020-2023  润新知