Command模式(C++實現)

來源:互聯網
上載者:User

標籤:

主要參考《大話設計模式》和《設計模式:可複用物件導向軟體的基礎》兩本書。本文介紹命令模式的實現。

          

What it is:Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.

將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支援可撤銷的操作。在OOP中,一切都是對象,將請求封裝成對象,符合OOP的設計思想,當將客戶的單個請求封裝成對象以後,我們就可以對這個請求儲存更多的資訊,使請求擁有更多的能力;命令模式同樣能夠把請求寄件者和接收者解耦,使得命令寄件者不用去關心請求將以何種方式被處理。

 

 

Command:聲明執行操作的介面;
ConcreteCommand:將一個接收者對象綁定於一個動作,之後,調用接收者相應的操作,以實現Execute來完成相應的命令;
Client:建立一個具體命令對象,但是並沒有設定它的接收者;
Invoker:要求該命令執行這個請求;
Receiver:知道如何實施與執行一個請求相關的操作,任何類都可能作為一個接收者。

以上這些對象是按照下面的方式進行協作的:

1.Client建立一個ConcreteCommand命令對象,並指定它的Receiver對象;
2.InvokerObject Storage Service該ConcreteCommand對象;
3.該Invoker通過調用Command對象的Execute操作來提交一個請求。如果這個命令請求是可以撤銷的,ConcreteCommand就執行Execute操作之前儲存目前狀態以用於取消該命令請求;
4.ConcreteCommand對象調用Receiver的一些操作以執行該請求。

 

具體案例:

我們去餐廳吃飯,我們是通過服務員來點菜,具體是誰來做這些菜和他們什麼時候完成的這些菜,其實我們都不知道。抽象之,我們是“菜單要求者”,廚師是“菜單實現者”,2者之間是松耦合的,我們對這些菜的其他一些請求比如“撤銷,重做”等,我們也不知道是誰在做。其實這就是本文要說的Command模式。將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支援可撤消的操作。[GOF 《設計模式》]

 

UML圖如下:

 

具體代碼C++代碼實現:

 1 #include <iostream>   2 #include <string> 3 #include <vector> 4 using namespace std; 5  6 #define SAFE_DELETE(p) if (p) { delete p; p = NULL; } 7  8 class Client 9 {};10 /*烤肉師傅類,只負責烤串工作*/11 class Barbecuer12 {13 public:14     void BakeMutton(){cout<<"Bake mutton"<<endl;}15     void BakeChickenWing(){cout<<"Bake ChickenWing"<<endl;}16 };17 18 /*抽象命令類:是執行具體操作的介面*/19 class Command20 {21 public:22     Command(){}23     Command(Barbecuer *receiver):p_receiver(receiver){}24     virtual void ExecuteCommand() = 0; //執行命令25 protected:26     Barbecuer *p_receiver;27 };28 29 /*具體命令類:烤羊肉串命令*/30 class BakeMuttonCommand:public Command31 {32 public:33     BakeMuttonCommand(Barbecuer *receiver){p_receiver = receiver;}34     void ExecuteCommand(){p_receiver->BakeMutton();}35 };36 37 /*具體命令類:烤雞翅串命令*/38 class BakeChickenWingCommand:public Command39 {40 public:41     BakeChickenWingCommand(Barbecuer *receiver){p_receiver = receiver;}42     void ExecuteCommand()43     {p_receiver->BakeChickenWing();}44 };45 46 /*服務員類*/47 class Waiter48 {49 public:50     void SetOrder(Command *command);51     void Notify();52 private:53     vector<Command *>p_commandList; //這裡相當於一個命令對象隊列54 };55 56 void Waiter::SetOrder(Command *command)57 {58     p_commandList.push_back(command);59     cout << "增加烤肉命令" << endl;60 }61 62 void Waiter::Notify()63 {64     vector<Command*>::iterator i;65     for(i = p_commandList.begin(); i != p_commandList.end(); ++ i)66         (*i)->ExecuteCommand();67 }68 69 int main(int argc, char *argv[])  70 {  71     //產生烤肉師傅、服務員、訂單對象72     Barbecuer *p_cook = new Barbecuer();73     Command *p_mutton = new BakeMuttonCommand(p_cook);74     Command *p_chickenwing = new BakeChickenWingCommand(p_cook);75     Waiter *p_waiter = new Waiter();76 77     //將訂單對象推送到命令隊列78     p_waiter->SetOrder(p_mutton);79     p_waiter->SetOrder(p_chickenwing);80 81     //服務員通知烤肉師傅具體訂單82     p_waiter->Notify();83 84     SAFE_DELETE(p_cook);85     SAFE_DELETE(p_mutton);86     SAFE_DELETE(p_chickenwing);87     SAFE_DELETE(p_waiter);88 89     return 0;  90 }

 

Command模式(C++實現)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.