命令模式
简介
参考链接
命令模式(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;
}