1.意圖 將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可撤銷的操作。 2.別名 動作(Action),事務(Transaction) 3.動機 命令模式通過將請求本身變成一個對象來使請求可向未指定的應用對象提出請求。這個對象可被存儲並像其他的對 ...
1.意圖
將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可撤銷的操作。
2.別名
動作(Action),事務(Transaction)
3.動機
命令模式通過將請求本身變成一個對象來使請求可向未指定的應用對象提出請求。這個對象可被存儲並像其他的對象一樣被傳遞。
4.適用性
- 抽象出待執行的動作以參數化某對象。
- 在不同的時刻指定、排列和執行請求
- 支持取消操作。
- 支持修改日誌,這樣當系統崩潰時,這些修改可以被重做一遍
- 用構建在原語操作上的高層操作構造一個系統。
5.結構
6.代碼實例
//Command.h #include <memory> class AbstractReceiver; class AbstractCommand { public: virtual void Execute() = 0; virtual void SetReceiver(std::shared_ptr<AbstractReceiver> receiver ); protected: std::shared_ptr<AbstractReceiver> m_Receiver; }; class ConcreteCommand1 : public AbstractCommand { public: void Execute(); }; class ConcreteCommand2 : public AbstractCommand { public: void Execute(); };
//Receiver.h class AbstractReceiver { public: virtual void Action() = 0; }; class ConcreteReceiver1 : public AbstractReceiver { public: void Action(); }; class ConcreteReceiver2 : public AbstractReceiver { public: void Action(); };
//Command.cpp #include <iostream> #include "Receiver.h" #include "Command.h" void AbstractCommand::SetReceiver(std::shared_ptr<AbstractReceiver> receiver) { m_Receiver = receiver; } void ConcreteCommand1::Execute() { m_Receiver->Action(); }; void ConcreteCommand2::Execute() { m_Receiver->Action(); };
//Receiver.cpp #include <iostream> #include "Receiver.h" void ConcreteReceiver1::Action() { std::cout << "Receiver1 Action Executed" << std::endl; }; void ConcreteReceiver2::Action() { std::cout << "Receiver2 Action Executed" << std::endl; };
//Client.cpp #include "Command.h" #include "Receiver.h" int main() { std::shared_ptr<AbstractCommand> pConcreteCommand1(new ConcreteCommand1); std::shared_ptr<AbstractCommand> pConcreteCommand2(new ConcreteCommand2); std::shared_ptr<AbstractReceiver> pReceiver1(new ConcreteReceiver1); std::shared_ptr<AbstractReceiver> pReceiver2(new ConcreteReceiver2); pConcreteCommand1->SetReceiver(pReceiver1); pConcreteCommand2->SetReceiver(pReceiver2); pConcreteCommand1->Execute(); pConcreteCommand2->Execute(); while(1); }
7.測試結果
8.效果
- 將調用操作的對象與知道如何實現該操作的對象解耦。
- Command對象是頭等的對象。它可以像其它對象一樣被操作和擴展。
- 可以將多個命令裝配成一個命令。
- 增加新的Command很容易,因為無需改變已有的類。