天天看點

設計模式(三)指令模式 C++

指令模式:将“請求”封裝成對象,以便使用不同的請求、隊列或者日志來參數化其他對象。指令模式也支援可撤銷的操作。

指令(Command):為所有指令聲明了一個接口。調用指令對象的 execute()方法,就可以讓接收者進行相關的操作。這個接口也具備一個 undo() 方法。

指令模式把請求一個操作的對象與知道怎麼執行一個操作的對象分隔開,進而使新的指令類可以很容易被加入到系統當中

組成部分

1、調用者(Invoker):持有一個指令對象,并在某個時間點調用指令對象的execute()方法。

2、指令對象(Command):持有一個接收者,和一個execute()方法,在execute中執行接收者的動作。

3、接收者(Receiver):動作的執行者。

優點:

1、能夠比較容易的設計一個指令隊列

2、需要的情況下,可以很容易的将指令記入日志

3、允許接受者決定是否要否決請求

4、可以很容易的實作對請求的撤銷和重做

5、新添加的指令類,不影響其它的類,是以新添加的具體指令類很容易

缺點:使用指令模式可能會導緻某些系統有過多的具體指令類。

應用場景:

1、真正需要撤銷\恢複等操作的時候,用指令模式

2、需要對指令記錄日志

#include <iostream>  
#include <string>
#include <list>
#include<windows.h>
using namespace std;

//typedef std::list<Command*> ListCommand; // 指令清單

#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;
  }
  void BakeChichenLeg()
  {
    cout << "Bake ChichenLeg" << 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();
  }
};

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

// 具體指令類
class BakeChickenLegCommand :public Command 
{
public:
  BakeChickenLegCommand(Barbecuer *receiver)
  {
    p_receiver = receiver;
  }
  void ExecuteCommand()
  {
    p_receiver->BakeChichenLeg();
  }

};
// 服務員類
class Waiter
{
public:
  void SetOrder(Command *command);

  void CancleOrder(Command *command);

  void Notify();
private:
  std::list<Command*> p_commandList; // 指令對象清單
};

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

void Waiter::CancleOrder(Command *command)
{
  p_commandList.remove(command);

  cout << "移除烤肉指令" << endl;
}
void Waiter::Notify()
{
  std::list<Command*>::iterator iterCommand;
  for (iterCommand = p_commandList.begin(); iterCommand != p_commandList.end(); ++iterCommand)
    (*iterCommand)->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);
  Command *p_chickenLeg = new BakeChickenLegCommand(p_cook);

  Waiter *p_waiter = new Waiter();

  // 顧客點菜
  p_waiter->SetOrder(p_mutton);
  p_waiter->SetOrder(p_chickenwing);
  p_waiter->SetOrder(p_chickenLeg);

  p_waiter->CancleOrder(p_chickenwing);

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

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

  system("pause");
  return 0;
}