命令模式,是将一个请求封装为一个对象,从而使我们可以用不同的请求对客户进行参数化、对请求排队或记录请求日志,以及支持可撤销的操作。
命令模式结构图
命令模式基本代码
#include <iostream>
#include <list>
using namespace std;
// Receiver类,知道如何实施与执行一个与请求相关的操作:
class Receiver {
public:
void Action() {
cout << "Receiver" << endl;
}
};
// Command类,用来声明执行操作的接口
class Command {
public:
virtual void Excute() = 0;
virtual void setReceiver(Receiver* r) = 0;
virtual ~Command(){};
};
// ConcreteCommand类,绑定一个Receiver,调用其相应操作以实现Excute:
class ConcreteCommand : public Command {
private:
Receiver* receiver;
public:
void setReceiver(Receiver* r) {
receiver = r;
}
void Excute() {
//cout << "ConcreteCommand" << endl;
receiver->Action();
}
};
// 要求该命令执行这个请求:
class Invoker {
private:
list<Command* > commands;
public:
void setCommand(Command* c) {
commands.push_back(c);
}
void Notify() {
for (auto c = commands.begin(); c != commands.end(); c++) {
(*c)->Excute();
}
}
};
// 客户端实现代码:
int main() {
Command* c = new ConcreteCommand();
Receiver* r = new Receiver();
c->setReceiver(r);
Invoker I;
i.setCommand(c);
i.Notify(); // Receiver
delete r;
delete c;
return 0;
}
应用场景
优点:
- 能较容易地设计一个命令队列;
- 在需要的情况下,可以较容易地将命令记入日志;
- 允许接收请求的一方决定是否要否决请求;
- 可以轻易地实现对请求的撤销和重做;
- 增加新的具体命令类很方便;
- 命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开了。