1. 程式人生 > >命令模式(c++實現)

命令模式(c++實現)

# 命令模式 [TOC] ## 模式定義 **命令模式(Command)**,將一個請求封裝為一個物件,從而使你可用不同的請求對客戶進行引數化;對請求排隊或記錄請求日誌,以及支援可撤銷的操作。 ## 模式動機 - 敏捷開發的原則告訴我們,不要為程式碼新增基於猜測的、實際不需要的功能。如果不清楚一個系統是否需要命令模式,一般就不要著急去實現它,事實上,在需要的時候通過重構實現這個模式並不困難,只有在真正需要如撤銷/恢復操作等功能時,把原來的程式碼重構為命令模式才有意義。 ## UML類圖 ![](https://files-cdn.cnblogs.com/files/wzxNote/%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F.bmp) ## 原始碼實現 - command.h ```c++ #include "chef.h" class Command { public: Command(Chef* chef); virtual ~Command(); virtual void ExcuteCmd(); protected: Chef* m_Chef; }; ``` - chef.h ```c++ class Chef { public: Chef(); void KungPaoChicken(); void FishFlavoredShreddedPork(); void BigPlateChicken(); }; ``` - chef.cpp ```c++ #include "chef.h" #include Chef::Chef() { } void Chef::KungPaoChicken() { std::cout << "宮保雞丁" << std::endl; } void Chef::FishFlavoredShreddedPork() { std::cout << "魚香肉絲" << std::endl; } void Chef::BigPlateChicken() { std::cout << "大盤雞" << std::endl; } ``` - kungpaochickencmd.h ```c++ #include "command.h" #include "chef.h" class KungPaoChickenCmd : public Command { public: KungPaoChickenCmd(Chef* chef); void ExcuteCmd() override; }; ``` - kungpaochickencmd.cpp ```c++ #include "kungpaochickencmd.h" KungPaoChickenCmd::KungPaoChickenCmd(Chef* chef) :Command(chef) { } void KungPaoChickenCmd::ExcuteCmd() { m_Chef->KungPaoChicken(); } ``` - waiter.h ```c++ #include #include class Waiter { public: Waiter(); void AddCmd(Command* cmd); void DelCmd(Command* cmd); void Nodify(); private: std::list m_CmdList; }; ``` - waiter.cpp ```c++ #include "waiter.h" Waiter::Waiter() { } void Waiter::AddCmd(Command *cmd) { m_CmdList.push_back(cmd); } void Waiter::DelCmd(Command *cmd) { m_CmdList.remove(cmd); } void Waiter::Nodify() { for(auto cmd : m_CmdList) { if(cmd) cmd->ExcuteCmd(); } } ``` - main.cpp ```c++ #include #include "fishflavoredshreddedporkcmd.h" #include "kungpaochickencmd.h" #include "bigplatechickencmd.h" #include "waiter.h" #include int main() { Chef* chef = new Chef(); Waiter waiter; std::shared_ptr ffspc = std::make_shared(chef); std::shared_ptr kpcc = std::make_shared(chef); std::shared_ptr bpcc = std::make_shared(chef); waiter.AddCmd(ffspc.get()); waiter.AddCmd(kpcc.get()); waiter.AddCmd(bpcc.get()); // waiter.DelCmd(kpcc.get); waiter.Nodify(); return 0; } ``` - 執行結果 > 魚香肉絲 > > 宮保雞丁 > > 大盤雞 ## 優點 命令模式的優點 - 它能較容易的設計一個命令佇列; - 在需要的情況下,可以較容易的將命令計入日誌; - 允許接收請求的一方決定是否要否決請求; - 可以容易的實現對請求的撤銷和重做; - 由於加進新的具體命令類不影響其他的類,因此增加新的具體命令類很容易; - 把請求一個操作的物件與知道怎麼執行一個操作的物件分隔開; ## 缺點 模式的缺點 -