Skip to content

命令模式

回到目录

简介

参考链接

命令模式(Command),将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

命令模式的优点

  • 它能较容易的设计一个命令队列;
  • 在需要的情况下,可以较容易的将命令计入日志;
  • 允许接收请求的一方决定是否要否决请求;
  • 可以容易的实现对请求的撤销和重做;
  • 由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易;
  • 把请求一个操作的对象与知道怎么执行一个操作的对象分隔开;

UML类图

代码示例

#include <iostream>
#include <list>
using namespace std;

// 执行动作
class Receiver
{
public:
  void Do1() {
    cout << "Receiver->Do1" <<endl;
  }
  void Revoke1() {
    cout << "Receiver->Revoke1" <<endl;
  }
};

class Command
{
public:
  virtual void Execute() = 0;
};

// 发起执行Do1动作
class CommandDo1 : public Command
{
public:
  CommandDo1(Receiver *pReceiver) : m_pReceiver(pReceiver) {}
  void Execute() {
    m_pReceiver->Do1();
  }
private:
  Receiver *m_pReceiver;
};

// 发起执行Revoke1动作
class CommandRevoke1 : public Command
{
public:
  CommandRevoke1(Receiver *pReceiver) : m_pReceiver(pReceiver) {}
  void Execute() {
    m_pReceiver->Revoke1();
  }
private:
  Receiver *m_pReceiver;
};

// 发起操作
class Invoker
{
public:
  Invoker() {}
  void AddCmd(Command* cmd) {
    m_CmdList.push_back(cmd);
  }
  void DelCmd(Command* cmd) {
    m_CmdList.remove(cmd);
  }
  void Invoke() {
    for(auto cmd : m_CmdList) {
      if(cmd) {
        cmd->Execute();
      }
    }
  }
private:
  std::list<Command *> m_CmdList;
};

int main()
{
  Receiver *pRecv = new Receiver();
  Command *pCommandDo1 = new CommandDo1(pRecv);
  Command *pCommandRevoke1 = new CommandRevoke1(pRecv);

  Invoker *pInvoker = new Invoker();
  pInvoker->AddCmd(pCommandDo1);
  pInvoker->DelCmd(pCommandDo1);
  pInvoker->AddCmd(pCommandRevoke1);
  pInvoker->Invoke();

  delete pRecv;
  delete pCommandDo1;
  delete pCommandRevoke1;
  delete pInvoker;

  return 0;
}