一. 举例说明

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

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

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

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

结构图如下:

代码如下:

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

二. 命令模式

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

优点:

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

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

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

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

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

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

设计模式C++描述----19.命令(Command)模式的更多相关文章

  1. 命令(Command)模式

    命令模式又称为行动(Action)模式或者交易(Transaction)模式. 命令模式把一个请求或者操作封装到一个对象中.命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可 ...

  2. 设计模式的征途—19.命令(Command)模式

    在生活中,我们装修新房的最后几道工序之一是安装插座和开关,通过开关可以控制一些电器的打开和关闭,例如电灯或换气扇.在购买开关时,用户并不知道它将来到底用于控制什么电器,也就是说,开关与电灯.换气扇并无 ...

  3. python 设计模式之命令(Command)模式

    #写在前面 也了解了不少设计模式了,他们都有一个通病,那就是喜欢把简单的东西复杂化.比如在不同的类中加个第三者.哈哈哈,简单变复杂是有目的的,那就是降低耦合度,增强可维护性,提高代码复用性,使代码变得 ...

  4. 十五、命令(Command)模式--行为型模式(Behavioral Pattern)

    命令模式又称为行动(Action)模 式或交易(Transaction)模式.命令模式把一个请求或者操作封装到一个对象中. 命令模式是对命令的封装.命令模式把发出命令的责任和执行命令的责任分割开,委派 ...

  5. 设计模式C++描述----21.解释器(Iterpreter)模式

    一. 解释器模式 定义:给定一个语言,定义它的文法的一种表示,并定一个解释器,这个解释器使用该表示来解释语言中的句子. 结构如下: 代码如下: //包含解释器之外的一些全局信息 class Conte ...

  6. 设计模式C++描述----09.桥接(Bridge)模式

    一. 举例 N年前: 计算机最先出来时,软件和硬件是一绑在一起的,比如IBM出了一台电脑,上面有一个定制的系统,假如叫 IBM_Win,这个IBM_Win系统当然不能在HP电脑上运行,同样HP出的HP ...

  7. 设计模式C++描述----22.访问者(Visitor)模式

    一. 访问者模式 定义:表示一个作用于某对象结构中的各元素的操作.它你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 结构如下: 二. 举例 假设有一项科学实验,是用来对比两种种子在不同环 ...

  8. 设计模式C++描述----20.迭代器(Iterator)模式

    一. 举例说明 我们知道,在 STL 里提供 Iterator 来遍历 Vector 或者 List 数据结构. Iterator 模式也正是用来解决对一个聚合对象的遍历问题,将对聚合的遍历封装到一个 ...

  9. 设计模式C++描述----17.备忘录(Memento)模式

    一. 备忘录模式 定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 结构图: 使用范围: Memento 模式比较适用于功能 ...

随机推荐

  1. ExcelDataReader read excel file

    上篇文章向大家介绍了用DocumentFormat.OpenXml.dll读取excel的方法,这里再向大家介绍一种轻量级简便的方法,用的是Excel.dll,及ICSharpCode.SharpZi ...

  2. Ubuntu下安装并使用sublime text 3(建议:先安装Package controls 后在看本教程,否则可能会安装不了)

    首先从Sublime Text官网下载合适的包 然后使用 tar -xvvf sublime_text_3_build_3207_x64.tar.bz2 解压: 再使用 mv sublime_text ...

  3. .Net Core 商城微服务项目系列(六):搭建自己的Nuget包服务器

    当我们使用微服务架构之后,紧接而来的问题便是服务之间的程序集引用问题,可能没接触过的同学不太理解这句话,都已经微服务化了为什么还要互相引用程序集,当然可以不引用.但是我们会有这样一种情况,我们的每个接 ...

  4. 【干货总结】:可能是史上最全的MySQL和PGSQL对比材料

    [干货总结]:可能是史上最全的MySQL和PGSQL的对比材料 运维了MySQL和PGSQL已经有一段时间了,最近接到一个数据库选型需求,于是便开始收集资料整理了一下,然后就有了下面的对比表 关键词: ...

  5. [Redis] Redis的基本数据结构

    key-value 通过key获取或设置value SET key value GET key SET server:name "fido" GET server:name SET ...

  6. d3.js 绘制北京市地铁线路状况图(部分)

    地铁线路图的可视化一直都是路网公司的重点,今天来和大家一起绘制线路图.先上图. 点击线路按钮,显示相应的线路.点击线路图下面的站间按钮(图上未显示),上报站间故障. 首先就是制作json文件,这个文件 ...

  7. 什么是线程调度器(Thread Scheduler)和时间分片(Time Slicing )?

    线程调度器是一个操作系统服务,它负责为 Runnable 状态的线程分配 CPU 时间. 一旦我们创建一个线程并启动它,它的执行便依赖于线程调度器的实现.同上一个问题,线程调度并不受到 Java 虚拟 ...

  8. 纯C语言写的按键驱动,将按键逻辑与按键处理事件分离~

    button drive 杰杰自己写的一个按键驱动,支持单双击.连按.长按:采用回调处理按键事件(自定义消抖时间),使用只需3步,创建按键,按键事件与回调处理函数链接映射,周期检查按键. 源码地址:h ...

  9. P3105 [USACO14OPEN]公平的摄影Fair Photography

    题意翻译 在数轴上有 NNN 头牛,第 iii 头牛位于 xi(0≤xi≤109)x_i\:(0\le x_i\le 10^9)xi​(0≤xi​≤109) .没有两头牛位于同一位置. 有两种牛:白牛 ...

  10. cocos2dx 3.2 内存管理

    一.引用计数(cocos2d-x3.2的Node类中用到) 概念:记录当前对象被引用的次数.当次数为0时释放. 1 . retain  与 release 每调用一次retain()使计数+1 每调用 ...