C++设计模式10--命令模式(二)(Command)--降低请求发送者与接收者耦合

简介:

  工作了一天感觉好累,洗了个澡,打开电视看看有没有喜欢的节目,拿起遥控器,看着上面的按钮,忽然感觉好奇妙,我们按一开机键,电视就开了,然后...哈哈,真好玩,我按我按。细想之下这不就是一个命令模式么。

电视机是请求的接收者Receiver

遥控器是请求的发送者ConcreteCommand

遥控器上有一些按钮,不同的按钮对应电视机的不同操作。

抽象命令角色由一个命令接口来扮演,有三个具体的命令类实现了抽象命令接口,这三个具体命令类分别代表三种操作:打开电视机、关闭电视机和切换频道。

显然,电视机遥控器就是一个典型的命令模式应用实例。

  1. #include <iostream>  
  2. #include <vector>  
  3. using std::cout;  
  4. using std::endl;  
  5. using std::vector;  
  6. using namespace std;  
  7. /* 
  8. 电视机是请求的接收者, 
  9.     也只有它的内部有一堆指令集合可以执行各种命令,它才是命令的真正执行者 
  10.     因此它有Open打开电视, Close关闭电视,Change更换频道的接口 
  11. 遥控器是请求的发送者, 
  12.     它内含命令的对象, 
  13.     负责将这个命令发送出去,因此需要有设置命令的接口,相当于人按下遥控器的按钮 
  14.     内含RunCommand运行命令的接口,它调用了命令接口的Execute执行函数 
  15.  
  16. 遥控器上的那些按钮, 
  17.     不同的按钮对应电视机的不同操作。 
  18.     抽象命令角色由一个命令接口来扮演, 
  19.     有三个具体的命令类实现了抽象命令接口, 
  20.     这三个具体命令类分别代表三种操作: 
  21.     打开电视机、关闭电视机和切换频道。 
  22.  
  23. 显然,电视机遥控器就是一个典型的命令模式应用实例。 
  24. */  
  25.   
  26.   
  27.   
  28.   
  29. // 接收者对象, 电视才是真正命令的执行者  
  30. class Television  
  31. {  
  32. public :  
  33.     void Open( )       // 打开电视  
  34.     {  
  35.         std::cout <<"打开电视" <<std::endl;  
  36.     }  
  37.   
  38.     void Close( )      // 关闭电视  
  39.     {  
  40.         std::cout <<"关闭电视" <<std::endl;  
  41.     }  
  42.   
  43.     void Change( )     // 切换频道  
  44.     {  
  45.         std::cout <<"更换频道" <<std::endl;  
  46.     }  
  47. };  
  48.   
  49.   
  50. class Command  
  51. {  
  52. public :  
  53.     virtual void Execute( ) = 0;         // 执行的接口  
  54. };  
  55.   
  56. // 打开电视的命令  
  57. class OpenCommand : public Command  
  58. {  
  59. public :  
  60.     OpenCommand(Television *tv)  
  61.     {  
  62.         m_tv = tv;  
  63.     }  
  64.   
  65.     void Execute( )         // 执行的接口  
  66.     {  
  67.         //std::cout <<"打开电视" <<std::endl;  
  68.         m_tv->Open( );  
  69.     }  
  70. protected :  
  71.     Television *m_tv;  
  72. };  
  73.   
  74. // 关闭电视的命令  
  75. class CloseCommand : public Command  
  76. {  
  77. public :  
  78.     CloseCommand(Television *tv)  
  79.     {  
  80.         m_tv = tv;  
  81.     }  
  82.     void Execute( )         // 执行的接口  
  83.     {  
  84.         //std::cout <<"关闭电视" <<std::endl;  
  85.         m_tv->Close( );  
  86.     }  
  87. protected :  
  88.     Television *m_tv;  
  89. };  
  90.   
  91. // 更换频道的命令  
  92. class ChangeCommand : public Command  
  93. {  
  94. public :  
  95.     ChangeCommand(Television *tv)  
  96.     {  
  97.         m_tv = tv;  
  98.     }  
  99.     void Execute( )         // 执行的接口  
  100.     {  
  101.         //std::cout <<"更换频道" <<std::endl;  
  102.         m_tv->Change( );  
  103.     }  
  104. protected :  
  105.     Television *m_tv;  
  106. };  
  107.   
  108. // Invoker请求发送者  
  109. // 要求命令对象执行请求,  
  110. // 通常会持有命令对象,可以持有很多的命令对象  
  111. class Control  
  112. {  
  113. public :  
  114.     void SetCommand(Command *command)  
  115.     {  
  116.        this->m_command = command;  
  117.     }  
  118.   
  119.     void RunCommand( )  
  120.     {  
  121.         m_command->Execute();  
  122.     }  
  123.   
  124. protected:  
  125.     Command *m_command;  
  126.   
  127. };  
  128.   
  129. // 主程序其实就相当于我们人  
  130. int main( )  
  131. {  
  132.     // 我们手里有一个遥控器  
  133.     Control *control = new Control;  
  134.   
  135.     // 家里有一个大彩电  
  136.     Television *tv = new Television;  
  137.   
  138.     /// 首先我们打开电视机  
  139.     // 创建一个打开的命令, 这个命令只操纵tv这个对象  
  140.     Command *openCommand = new OpenCommand(tv);  
  141.     control->SetCommand(openCommand);  
  142.     control->RunCommand( );  
  143.     delete openCommand;  
  144.   
  145.   
  146.     // 换了好久频道也没找到好看的, 郁闷的关掉电视机  
  147.     // 创建一个更换频道的命令,这个命令只操纵tv这个对象  
  148.     Command *changeCommand = new ChangeCommand(tv);  
  149.     control->SetCommand(changeCommand);  
  150.     control->RunCommand( );  
  151.     delete changeCommand;  
  152.   
  153.     // 换了好久频道也没找到好看的, 郁闷的关掉电视机  
  154.     // 创建一个关闭的命令, 这个命令只操纵tv这个对象  
  155.     Command *closeCommand = new CloseCommand(tv);  
  156.     control->SetCommand(closeCommand);  
  157.     control->RunCommand( );  
  158.     delete closeCommand;  
  159.   
  160.     delete tv;  
  161.     delete control;  
  162.     return 0;  
  163. }  


转载:http://blog.csdn.net/gatieme/article/details/18044097

目录
相关文章
|
1月前
|
设计模式 存储 算法
Java设计模式-命令模式(16)
Java设计模式-命令模式(16)
|
2月前
|
设计模式 存储 Java
【十二】设计模式~~~行为型模式~~~命令模式(Java)
文章详细介绍了命令模式(Command Pattern),这是一种对象行为型模式,用于将请求封装成对象,实现请求发送者与接收者的解耦,从而降低系统耦合度、提高灵活性,并支持命令的排队、记录、撤销和恢复操作。通过案例分析、结构图、时序图和代码示例,文章展示了命令模式的组成部分、实现方式和应用场景,并讨论了其优点、缺点和适用情况。
|
3月前
|
设计模式 C++
C++一分钟之-设计模式:工厂模式与抽象工厂
【7月更文挑战第14天】设计模式是解决软件设计问题的通用方案。工厂模式与抽象工厂模式是创建型模式,用于对象创建而不暴露创建逻辑。工厂模式推迟实例化到子类,但过度使用会增加复杂性。抽象工厂则创建相关对象族,但过度抽象可能造成不必要的复杂度。两者均应按需使用,确保设计灵活性。代码示例展示了C++中如何实现这两种模式。
40 3
|
3月前
|
设计模式 安全 C++
C++一分钟之-C++中的设计模式:单例模式
【7月更文挑战第13天】单例模式确保类只有一个实例,提供全局访问。C++中的实现涉及线程安全和生命周期管理。基础实现使用静态成员,但在多线程环境下可能导致多个实例。为解决此问题,采用双重检查锁定和`std::mutex`保证安全。使用`std::unique_ptr`管理生命周期,防止析构异常和内存泄漏。理解和正确应用单例模式能提升软件的效率与可维护性。
42 2
|
3月前
|
设计模式 JavaScript API
js设计模式【详解】—— 命令模式
js设计模式【详解】—— 命令模式
39 6
|
4月前
|
设计模式 Java uml
必知的技术知识:JAVA【设计模式】命令模式
必知的技术知识:JAVA【设计模式】命令模式
27 0
|
4月前
|
设计模式 Java
Java设计模式之命令模式详解
Java设计模式之命令模式详解
|
29天前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
8天前
|
设计模式 Java Kotlin
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
本教程详细讲解Kotlin语法,适合希望深入了解Kotlin的开发者。对于快速学习Kotlin语法,推荐查看“简洁”系列教程。本文重点介绍了构建者模式在Kotlin中的应用与改良,包括如何使用具名可选参数简化复杂对象的创建过程,以及如何在初始化代码块中对参数进行约束和校验。
13 3
|
1月前
|
设计模式 算法 安全
设计模式——模板模式
模板方法模式、钩子方法、Spring源码AbstractApplicationContext类用到的模板方法
设计模式——模板模式