CommandModel.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #ifndef __COMMANDMODEL_H__
  2. #define __COMMANDMODEL_H__
  3. #include "spdlog/spdlog.h"
  4. #include <map>
  5. #include <list>
  6. /**
  7. 命令模式
  8. 定义:将一个请求封装为一个对象,从而使您可以用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
  9. UML类图:
  10. Client(客户端)
  11. Invoker(调用者)
  12. Command(抽象命令)
  13. ┌───┴──────────┐
  14. ConcreteCommandA ConcreteCommandB(具体命令)
  15. Receiver(接收者)
  16. 角色:
  17. Command(命令接口):定义 execute() 方法,封装执行逻辑。
  18. ConcreteCommand(具体命令):实现 Command,并持有 Receiver,调用其方法执行具体操作。
  19. Receiver(接收者):实际执行操作的对象,提供具体的功能实现。
  20. Invoker(调用者):持有 Command 对象,触发 execute(),可以支持命令队列、撤销等功能。
  21. Client(客户端):创建 Command 对象,并将其传递给 Invoker。
  22. 优点:
  23. 1、降低了命令的发起者与命令的执行者之间的耦合度。
  24. 2、新的命令可以很容易地加入到系统中。
  25. 3、可以比较容易地设计一个命令队列和宏命令。
  26. 4、可以方便地实现对请求的撤销和重做。
  27. 缺点:
  28. 1、使用命令模式可能会导致某些系统有过多的具体命令类。
  29. 适用场景:
  30. 1、系统需要将请求调用者与请求接收者解耦时。
  31. 2、系统需要支持命令的撤销(Undo)和重做(Redo)操作时。
  32. 3、系统需要将一组操作组合在一起,即支持宏命令(Macro Command)时。
  33. 示例:
  34. 使用命令模式实现只能家居
  35. */
  36. namespace CommandModel {
  37. /* =========================================================
  38. * 命令接收者,这里是设置,会有多个具体的接收者
  39. * ========================================================= */
  40. /* 灯光 */
  41. class Light
  42. {
  43. public:
  44. void on() {
  45. SPDLOG_INFO("灯光已打开");
  46. }
  47. void off() {
  48. SPDLOG_INFO("灯光已关闭");
  49. }
  50. };
  51. class TV
  52. {
  53. public:
  54. void on() {
  55. SPDLOG_INFO("电视已打开");
  56. }
  57. void off() {
  58. SPDLOG_INFO("电视已关闭");
  59. }
  60. };
  61. /* =========================================================
  62. * 命令接口
  63. * ========================================================= */
  64. /* 抽象命令 */
  65. class AbstractCommand
  66. {
  67. public:
  68. virtual ~AbstractCommand() = default;
  69. virtual void execute() = 0;
  70. virtual void undo() = 0;
  71. };
  72. /* 开灯命令 */
  73. class LightOnCommand : public AbstractCommand
  74. {
  75. public:
  76. LightOnCommand(Light* light) : m_light(light) {}
  77. void execute() override {
  78. m_light->on();
  79. }
  80. void undo() override {
  81. m_light->off();
  82. }
  83. private:
  84. Light* m_light;
  85. };
  86. /* 关灯命令 */
  87. class LightOffCommand : public AbstractCommand
  88. {
  89. public:
  90. LightOffCommand(Light* light) : m_light(light) {}
  91. void execute() override {
  92. m_light->off();
  93. }
  94. void undo() override {
  95. m_light->on();
  96. }
  97. private:
  98. Light* m_light;
  99. };
  100. /* 开电视命令 */
  101. class TVOnCommand : public AbstractCommand
  102. {
  103. public:
  104. TVOnCommand(TV* tv) : m_tv(tv) {}
  105. void execute() override {
  106. m_tv->on();
  107. }
  108. void undo() override {
  109. m_tv->off();
  110. }
  111. private:
  112. TV* m_tv;
  113. };
  114. /* 关电视命令 */
  115. class TVOffCommand : public AbstractCommand
  116. {
  117. public:
  118. TVOffCommand(TV* tv) : m_tv(tv) {}
  119. void execute() override {
  120. m_tv->off();
  121. }
  122. void undo() override {
  123. m_tv->on();
  124. }
  125. private:
  126. TV* m_tv;
  127. };
  128. /* =========================================================
  129. * 调用者,这里是遥控器,这个遥控器是万能遥控器,可以控制所有设备
  130. * ========================================================= */
  131. /* 遥控器设备 */
  132. class RemoteControl
  133. {
  134. public:
  135. /* 设置命令(添加命令) */
  136. void setCommand(int slot, AbstractCommand* command);
  137. /* 执行命令 */
  138. void pressButton(int dev);
  139. /* 撤销命令 */
  140. void pressUndo(int dev, int count = 1);
  141. private:
  142. /* 即将要执行的命令列表 */
  143. std::map<int, std::list<AbstractCommand*>> m_commands;
  144. /* 可撤销的命令(已执行过的) */
  145. std::map<int, AbstractCommand*> m_undoCommands;
  146. };
  147. /* 使用遥控器 */
  148. void useRemoteControl();
  149. }
  150. #endif /* __COMMANDMODEL_H__ */