設計模式--行爲型模式

行爲型模式

行爲型模式 類型
關注對象之間的通信 命令模式(Command Pattern)
責任鏈模式(Chain of Responsibility Pattern )
解釋器模式(Interpreter Pattern)
迭代器模式(Iterator Pattern)
中介者模式(Mediator Pattern)
備忘錄模式(Memento Pattern)
觀察者模式(Observer Pattern)
狀態模式(State Pattern)
空對象模式(Null Object Pattern)
策略模式(Strategy Pattern)
模板模式(Template Pattern)
訪問者模式(Visitor Pattern)

命令模式

命令模式(Command Pattern)是一種數據驅動的設計模式,它屬於行爲型模式。請求以命令的形式包裹在對象中,並傳給調用對象。調用對象尋找可以處理該命令的合適的對象,並把該命令傳給相應的對象,該對象執行命令

意圖:將一個請求封裝成一個對象,從而使您可以用不同的請求對客戶進行參數化。 在OOP中,一切都是對象,將請求封裝成對象,符合OOP的設計思想,當將客戶的單個請求封裝成對象以後,我們就可以對這個請求存儲更多的信息,使請求擁有更多的能力;命令模式同樣能夠把請求發送者和接收者解耦,使得命令發送者不用去關心請求將以何種方式被處理。
在這裏插入圖片描述

參與者

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

協作

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

優點

  1. 降低了系統耦合度。
  2. 新的命令可以很容易添加到系統中去。

缺點

  1. 使用命令模式可能會導致某些系統有過多的具體命令類。

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

在這裏插入圖片描述



#include <iostream>  
#include <string>
#include <vector>
using namespace std;

#define SAFE_DELETE(p) if (p) { delete p; p = NULL; }

/*烤肉師傅類,只負責烤串工作*/
class Barbecuer
{
public:
    void BakeMutton(){cout<<"Bake mutton"<<endl;}
    void BakeChickenWing(){cout<<"Bake ChickenWing"<<endl;}
};

/*抽象命令類:是執行具體操作的接口*/
class Command
{
public:
    Command(){}
    Command(Barbecuer *receiver):p_receiver(receiver){}
    virtual void ExecuteCommand() = 0; //執行命令
protected:
    Barbecuer *p_receiver;
};

/*具體命令類:烤羊肉串命令*/
class BakeMuttonCommand:public Command
{
public:
    BakeMuttonCommand(Barbecuer *receiver){p_receiver = receiver;}
    void ExecuteCommand(){p_receiver->BakeMutton();}
};

/*具體命令類:烤雞翅串命令*/
class BakeChickenWingCommand:public Command
{
public:
    BakeChickenWingCommand(Barbecuer *receiver){p_receiver = receiver;}
    void ExecuteCommand()
    {p_receiver->BakeChickenWing();}
};

/*服務員類*/
class Waiter
{
public:
    void SetOrder(Command *command);
    void Notify();
private:
    vector<Command *>p_commandList; //這裏相當於一個命令對象隊列
};

void Waiter::SetOrder(Command *command)
{
    p_commandList.push_back(command);
    cout << "增加烤肉命令" << endl;
}

void Waiter::Notify()
{
    vector<Command*>::iterator i;
    for(i = p_commandList.begin(); i != p_commandList.end(); ++ i)
        (*i)->ExecuteCommand();
}

int main(int argc, char *argv[])  
{  
    //生成烤肉師傅、服務員、訂單對象
    Barbecuer *p_cook = new Barbecuer();
    Command *p_mutton = new BakeMuttonCommand(p_cook);
    Command *p_chickenwing = new BakeChickenWingCommand(p_cook);
    Waiter *p_waiter = new Waiter();

    //將訂單對象推送到命令隊列
    p_waiter->SetOrder(p_mutton);
    p_waiter->SetOrder(p_chickenwing);

    //服務員通知烤肉師傅具體訂單
    p_waiter->Notify();

    SAFE_DELETE(p_cook);
    SAFE_DELETE(p_mutton);
    SAFE_DELETE(p_chickenwing);
    SAFE_DELETE(p_waiter);

    return 0;  
}

參考:
https://www.cnblogs.com/lizhanwu/p/4435359.html
https://www.runoob.com/design-pattern/command-pattern.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章