C++设计模式--命令模式(Command)
概述
命令模式的結構很簡單,但是對于消除代碼間的耦合卻有著重要的影響。命令模式就是一個函數對象:一個作為對象的函數。通過將函數封裝為對象,就能夠以參數的形式將其傳遞給其他函數或者對象,告訴它們在旅行請求的過程中執(zhí)行特定的操作。
命令模式
根據以上定義,來看一個簡單的示例:
/*** 命令模式,消除代碼間的耦合*/ #include <iostream> #include <vector>using namespace std;class Command { public:virtual void excute() = 0;virtual ~Command(); };class Hello : public Command { public:void excute(){cout << "Hello ";}virtual ~Hello(); }; class World : public Command { public:void excute(){cout << "World! ";}virtual ~World(); }; class IAm : public Command { public:void excute(){cout << "I'm the command pattern ";}virtual ~IAm(); };class Macro { public:void add(Command* c){commands.push_back(c);}void run(){vector<Command*>::iterator it = commands.begin();while(it != commands.end()){(*it++)->excute();}} private:vector<Command*> commands; };int main() {Macro macro;macro.add(new Hello);macro.add(new World);macro.add(new IAm);macro.run();return 0; }命令模式的最主要特點是允許一個函數或者對象傳遞一個想要的動作,上述示例提供了將一系列想要一起執(zhí)行的動作集進行排隊的方法。
命令模式一個常見的例子就是在應用程序中“撤銷操作”功能的實現,沒在在用戶進行某項操作的時候,相應的“撤銷操作”命令對象就被置入一個隊列中,而每個命令對象被執(zhí)行之后,程序的狀態(tài)就倒退一步。
利用命令模式消除與事件處理的耦合
命令模式可用來消除程序中的耦合問題。每個“常規(guī)”的操作必須周期性地調用一個函數來檢查事件的狀態(tài),而通過命令模式,這些“常規(guī)”操作不需要知道有關它們所檢查的事件的任何信息,也就是說它們已經與事件處理代碼分離開來。
示例:
#include <iostream> #include <vector> #include <string> #include <ctime> #include <cstdlib>using namespace std;class Task { public:virtual void operation() = 0; };//單例 class TaskRunner { public:static void add(Task& t){tasks.push_back(&t);}static void run(){vector<Task*>::iterator it = tasks.begin();while (it != tasks.end()) {(*it++)->operation();}}private:static vector<Task*> tasks;TaskRunner(){}static TaskRunner tr; };TaskRunner TaskRunner::tr; vector<Task*> TaskRunner::tasks;//創(chuàng)建隨機延遲時間 //clock() 返回從開啟程序進程到調用clock()時的時間。 class EventSimulator { public:EventSimulator():creation(clock()) {delay = CLOCKS_PER_SEC/4 * (rand() % 20 + 1);cout << "delay = " << delay << endl;}bool fired(){return clock() > creation + delay;}private:clock_t creation;clock_t delay; };class Button{ public:Button(string name):pressed(false),id(name){}void press(){pressed = true;}bool isPressed(){if(e.fired()) press();return pressed;}friend ostream& operator <<(ostream & os,const Button& b){return os << b.id;}private:bool pressed;string id;EventSimulator e; };class CheckButton : public Task { public:CheckButton(Button & b):button(b),handled(false) {}void operation(){if(button.isPressed() && !handled){cout << button << " pressed" << endl;handled = true;}}private:Button & button;bool handled; };void procedure1(){TaskRunner::run(); // check all events } void procedure2(){TaskRunner::run(); // check all events } void procedure3(){TaskRunner::run(); // check all events }int main() {srand(time(0));Button b1("Button 1"),b2("Button 2"),b3("Button 3");CheckButton cb1(b1),cb2(b2),cb3(b3);TaskRunner::add(cb1);TaskRunner::add(cb2);TaskRunner::add(cb3);cout<< "Control-C to exit" << endl;while (true) {procedure1();procedure2();procedure3();}return 0; }輸出為:
delay = 4500000 delay = 3000000 delay = 3000000 Control-C to exit Button 2 pressed Button 3 pressed Button 1 pressed這個示例中,命令對象由被單例 TaskRunner執(zhí)行的 Task 表示。EventSimulator創(chuàng)建一個隨機延遲時間,所以當周期性的調用函數fired()時,在某個隨機時間段,其返回結果從 true 和 false 變化。EventSimulator對象類 Button 中使用,模擬在某個不可預知的時間段用戶時間發(fā)生的動作。CheckButton 是Task 的實現,在程序中通過所有“正常”代碼對其進行周期性檢查,就是這里的procedure1(),procedure2(),procedure3()的末尾。
參考資料《C++編程思想》。
總結
以上是生活随笔為你收集整理的C++设计模式--命令模式(Command)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++设计模式--状态模式(state)
- 下一篇: C++设计模式--模板方法模式