019 --- 第23章 命令模式
简述:
命令模式:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数话;对请求队列化或记录请求日志,以及支持可撤销的操作。
命令模式包括:命令者类、命令类、接收者类、具体命令类。
命令者类:要求该命令执行这个请求,封装了命令类的队列。
命令类:抽象命令,用来声明执行操作的接口。
接收者类:知道如何实施与执行一个请求相关的操作,任何类都可能作为一个接收者。
具体命令类:将一个接收者对象绑定一个动作,调用接收者响应的操作,以实现执行具体命令。
应用场景:命令者类内部封装命令队列,请求执行命令,命令类封装执行者执行具体命令,可以容易的实现命令队列、记录日志、命令者类确定是否否决请求、撤销和重做
注:开发环境调整为VS2017,操作系统win11
命令模式:
1 // 接收者类 2 class CReceiver 3 { 4 public: 5 void Action() 6 { 7 cout << "执行请求!" << endl; 8 } 9 }; 10 11 // 命令类 12 class CCommand 13 { 14 protected: 15 CReceiver* m_pReceiver; 16 17 public: 18 CCommand(CReceiver* pReceiver) 19 { 20 m_pReceiver = pReceiver; 21 } 22 23 virtual void Execute() = 0; 24 }; 25 26 // 具体命令类 27 class CConcreteCommand : public CCommand 28 { 29 public: 30 CConcreteCommand(CReceiver* pReceiver) : CCommand(pReceiver) {} 31 32 virtual void Execute() 33 { 34 m_pReceiver->Action(); 35 } 36 }; 37 38 // 命令者类 39 class CInvoker 40 { 41 private: 42 CCommand* m_pCommand; 43 44 public: 45 void SetCommand(CCommand* pCommand) 46 { 47 m_pCommand = pCommand; 48 } 49 50 void ExecuteCommand() 51 { 52 m_pCommand->Execute(); 53 } 54 }; 55 56 int main() 57 { 58 CReceiver Receiver; 59 CConcreteCommand Command(&Receiver); 60 CInvoker Invoker; 61 Invoker.SetCommand(&Command); 62 Invoker.ExecuteCommand(); 63 64 system("pause"); 65 return 0; 66 }
输出结果:
例:串店点串
代码如下:
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <iostream> 3 #include <list> 4 #include <time.h> 5 #include <Windows.h> 6 using namespace std; 7 8 // 烤肉串者类(接收者类) 9 class CBarbecuer 10 { 11 public: 12 void BakeMutton() 13 { 14 cout << "烤羊肉串" << endl; 15 } 16 17 void BakeChickenWing() 18 { 19 cout << "烤鸡翅" << endl; 20 } 21 }; 22 23 // 命令类 24 class CCommand 25 { 26 protected: 27 CBarbecuer* m_pBarbecuer; 28 29 public: 30 CCommand(CBarbecuer* pBarbecuer) 31 { 32 m_pBarbecuer = pBarbecuer; 33 } 34 35 // 执行命令 36 virtual void ExecuteCommand() = 0; 37 }; 38 39 // 烤羊肉串命令类(具体命令类) 40 class CBakeMuttonCommand : public CCommand 41 { 42 public: 43 CBakeMuttonCommand(CBarbecuer* pBarbecuer) : CCommand(pBarbecuer) {} 44 45 virtual void ExecuteCommand() 46 { 47 m_pBarbecuer->BakeMutton(); 48 } 49 }; 50 51 // 烤鸡翅命令类(具体命令类) 52 class CBakeChickenWingCommand : public CCommand 53 { 54 public: 55 CBakeChickenWingCommand(CBarbecuer* pBarbecuer) : CCommand(pBarbecuer) {} 56 57 virtual void ExecuteCommand() 58 { 59 m_pBarbecuer->BakeChickenWing(); 60 } 61 }; 62 63 // 服务员类(命令者类) 64 class CWaiter 65 { 66 private: 67 //CCommand* m_pCommand; 68 list<CCommand*> m_lstCommand; 69 70 public: 71 // 设置订单 72 void SetOrder(CCommand* pCommand) 73 { 74 //m_pCommand = pCommand; 75 if (typeid(*pCommand) == typeid(CBakeChickenWingCommand)) 76 { 77 cout << "服务员:鸡翅没有了,请点别的烧烤。" << endl; 78 } 79 80 if(typeid(*pCommand) == typeid(CBakeMuttonCommand)) 81 { 82 m_lstCommand.push_back(pCommand); 83 time_t now = time(0); 84 cout << "增加订单:烤羊肉串 -> 时间:" << asctime(localtime(&now)); 85 } 86 } 87 88 // 取消订单 89 void CancelOrder(CCommand* pCommand) 90 { 91 if (typeid(*pCommand) == typeid(CBakeChickenWingCommand)) 92 { 93 m_lstCommand.remove(pCommand); 94 time_t now = time(0); 95 cout << "取消订单:烤鸡翅 -> 时间:" << asctime(localtime(&now)); 96 } 97 98 if (typeid(*pCommand) == typeid(CBakeMuttonCommand)) 99 { 100 m_lstCommand.remove(pCommand); 101 time_t now = time(0); 102 cout << "取消订单:烤羊肉串 -> 时间:" << asctime(localtime(&now)); 103 } 104 105 } 106 107 // 通知执行 108 void Notify() 109 { 110 //m_pCommand->ExecuteCommand(); 111 for (auto pCommand : m_lstCommand) 112 pCommand->ExecuteCommand(); 113 } 114 }; 115 116 int main() 117 { 118 // 开店前准备 119 CBarbecuer Barbecuer; 120 CBakeMuttonCommand BakeMuttonConmmand1(&Barbecuer); 121 CBakeMuttonCommand BakeMuttonConmmand2(&Barbecuer); 122 CBakeChickenWingCommand BakChickenWingConmmand1(&Barbecuer); 123 CWaiter Waiter; 124 125 // 开门营业,顾客点菜 126 Waiter.SetOrder(&BakeMuttonConmmand1); 127 Waiter.SetOrder(&BakeMuttonConmmand2); 128 Waiter.SetOrder(&BakChickenWingConmmand1); 129 Sleep(2000); 130 Waiter.CancelOrder(&BakChickenWingConmmand1); 131 // 点菜完毕,通知厨房 132 Waiter.Notify(); 133 134 system("pause"); 135 return 0; 136 }
输出结果: