设计模式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)分割开来。

原文地址:https://www.cnblogs.com/any91/p/3248018.html