C++設計模式 - 命令模式(Command)
阿新 • • 發佈:2022-03-25
行為變化模式
- 在元件的構建過程中,元件行為的變化經常導致元件本身劇烈的變化。“行為變化” 模式將元件的行為和元件本身進行解耦,從而支援元件行為的變化,實現兩者之間的鬆耦合。
典型模式
- Command
- Visitor
Command
動機( Motivation )
- 在軟體構建過程中,“行為請求者” 與"行為實現者”通常呈現一種“緊耦合”。但在某些場合一比如需 要對行為進行“記錄、撤銷/重(undo/redo)、事務”等處理,這種無法抵禦變化的緊耦合是不合適的。
- 在這種情況下,如何將“行為請求者”與“行為實現者”解耦?將一組行為抽象為物件,可以實現二者之間的鬆耦合。
模式定義
將一個請求(行為)封裝為一個物件,從而使你可用不同的請求對客戶進行引數化;對請求排隊或記錄請求日誌,以及支援可撤銷的操作。
結構
要點總結
- Command模式的根本目的在於將“行為請求者”與“行為實現者”解耦,在面嚮物件語言中,常見的實現手段是“將行為抽象為物件”
- 實現Command介面的具體命令物件ConcreteCommand有時候根據需要可能會儲存一些額外的狀態資訊。通過使用Composite模式 ,可以將多個”命令”封裝為一個“複合命令”MacroCommand.
- Command模式與C++中的函式物件有些類似。但兩者定義行為介面的規範有所區別: Command以面向物件中的' 介面-實現”來定義行為介面規範,更嚴格,但有效能損失; C++函式物件以函式簽名來定義行為介面規範,更靈活,效能更高。
cpp
#include<string> #include<iostream> #include<vector> class Command { public: virtual void execute() = 0; virtual ~Command() {} }; class ConcreteCommand1 :public Command { public: ConcreteCommand1(const std::string& str) :arg(str) {} void execute() override { std::cout << "#1 process..." << arg << std::endl; } private: std::string arg; }; class ConcreteCommand2 :public Command { public: ConcreteCommand2(const std::string& str) :arg(str) {} void execute() override { std::cout << "#2 process..." << arg << std::endl; } private: std::string arg; }; class MacroCommand :public Command { public: void addCommand(Command* command) { commands.push_back(command); } void execute() override { for (auto& c : commands) { c->execute(); } } private: std::vector<Command*>commands; }; int main() { ConcreteCommand1 command1("Arg ###"); ConcreteCommand2 command2("Arg $$$"); MacroCommand macro; macro.addCommand(&command1); macro.addCommand(&command2); macro.execute(); return 0; }