• 设计模式C++描述----19.命令(Command)模式


    一. 举例说明

    我们知道,在多线程程序中,多个用户都给系统发 Read 和 Write 命令。这里有几点需要说明:

    1. 首先明确一点,所有的这些 Read 和 Write 命令都是调用一个库函数。

    2. 用户并不需要知道别的用户的存在,也不管别人发不发命令,只管自己发命令,最后给结果即可。

    3. 这些命令先是到了一个消息队列里面,然后由消息队列调用库函数。

    结构图如下:

    代码如下:

    1. class Command;  
    2.   
    3. //实施与执行类  
    4. class Reciever   
    5. {   
    6. public:   
    7.     void Action()  
    8.     {  
    9.         cout<<"Do action !!"<<endl;  
    10.     }  
    11. };  
    12.   
    13. //抽象命令类  
    14. class Command   
    15. {   
    16. public:   
    17.     virtual ~Command() {}  
    18.   
    19.     virtual void Excute() = 0;  
    20.   
    21. protected:   
    22.     Command() {}  
    23. };  
    24.   
    25. //Read 命令  
    26. class Read_Command:public Command   
    27. {   
    28. public:   
    29.     Read_Command(Reciever* rev)  
    30.     {  
    31.         this->_rev = rev;  
    32.     }  
    33.   
    34.     ~Read_Command()  
    35.     {  
    36.         delete this->_rev;  
    37.     }  
    38.   
    39.     void Excute()  
    40.     {  
    41.         cout<<"Read Command..."<<endl;   
    42.         _rev->Action();  
    43.     }  
    44.   
    45. private:   
    46.     Reciever* _rev;   
    47. };  
    48.   
    49. //Write 命令  
    50. class Write_Command:public Command   
    51. {   
    52. public:   
    53.     Write_Command(Reciever* rev)  
    54.     {  
    55.         this->_rev = rev;  
    56.     }  
    57.       
    58.     ~Write_Command()  
    59.     {  
    60.         delete this->_rev;  
    61.     }  
    62.       
    63.     void Excute()  
    64.     {  
    65.         cout<<"Write_Command..."<<endl;   
    66.         _rev->Action();  
    67.     }  
    68.       
    69. private:   
    70.     Reciever* _rev;   
    71. };  
    72.   
    73. //要求命令执行的类  
    74. class Invoker  
    75. {   
    76. public:   
    77.     Invoker(Command* cmd)  
    78.     {  
    79.         _cmd = cmd;  
    80.     }  
    81.   
    82.     Invoker()  
    83.     {  
    84.     }  
    85.   
    86.     ~Invoker()  
    87.     {  
    88.         delete _cmd;  
    89.     }  
    90.   
    91.     //通知执行类执行  
    92.     void Notify()  
    93.     {  
    94.         list<Command*>::iterator it = cmdList.begin();  
    95.           
    96.         for (it; it != cmdList.end(); ++it)  
    97.         {  
    98.             _cmd = *it;  
    99.           _cmd->Excute();  
    100.         }  
    101.     }  
    102.   
    103.     //添加命令  
    104.     void AddCmd(Command* pcmd)  
    105.     {  
    106.         cmdList.push_back(pcmd);  
    107.     }  
    108.       
    109.     //删除命令  
    110.     void DelCmd(Command* pcmd)  
    111.     {  
    112.         cmdList.remove(pcmd);  
    113.     }  
    114.   
    115. private:   
    116.     Command* _cmd;   
    117.   
    118.     list<Command*> cmdList;  
    119. };  
    120.   
    121.   
    122. //测试代码  
    123. int main(int argc,char* argv[])   
    124. {   
    125.     Reciever* rev = new Reciever(); //定义一个执行类  
    126.       
    127.     Command* cmd1 = new Read_Command(rev);//Read 命令  
    128.     Command* cmd2 = new Write_Command(rev);//Write 命令  
    129.   
    130.     Invoker inv; //管理所有命令  
    131.       
    132.     inv.AddCmd(cmd1);  
    133.     inv.AddCmd(cmd2);  
    134.     inv.Notify(); //通知执行类,执行  
    135.   
    136.     inv.DelCmd(cmd1);  
    137.     inv.Notify();  
    138.   
    139.     return 0;   
    140. }  

    二. 命令模式

    定义:将一个请求封装为一个对象,从而使你可用不同的请求对客户时行参数化;对请求排队或记录请求日志,以及支持可撤销的操作


    优点:

    1. 它能比较容易地设计一个命令队列。

    2. 在需要的情况下,可以较容易地将命令记入日志。

    3. 允许接收请求的一方决定是否要否决请求。

    4. 可以容易地实现对请求的撤销和重做。

    5. 增加新的具体命令类很容易

    6. 把请求一个操作的对象(Command)与知道怎么执行一个操作的对象(Receiver)分割开来。

  • 相关阅读:
    添加右键菜单
    闭包和迭代器
    函数的进阶
    函数入门
    文件操作
    深浅拷贝
    小数据池和再谈编码
    字典
    list tuple
    int bool str
  • 原文地址:https://www.cnblogs.com/any91/p/3248018.html
Copyright © 2020-2023  润新知