1. 意图
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请
求日志,以及支持可撤销的操作。
2. 四种角色
接收者(Receiver)、抽象命令(Command)、具体命令(Concrete Command)、请求者(Invoker)
3. 优点
3.1 将调用方(请求者)和操作方(接收者)解耦。
3.2 命令对象可以被操纵和扩展。
3.3 可以将多个命令装配成一个复合命令。
3.4 容易增加新的命令,无需改变已有的类。
4. 缺点
N/A
5. 相关模式
5.1 组合模式可被用来实现宏命令。
5.2 Memento模式可用来保持某个状态,命令用这一状态来撤消。
5.3 允许被拷贝的命令用原型模式。
6. 代码示意(C++)
#pragma once
#include <iostream>
#include <vector>
using namespace std;
class Receiver
{
public:
void Action1() {
cout << "西红柿炒鸡蛋已完成" << endl;
}
void Action2() {
cout << "凉瓜牛肉已完成" << endl;
}
};
class Command
{
protected:
Receiver* m_pReceiver;//命令接收者
public:
Command(Receiver* pReceiver) {
m_pReceiver = pReceiver;
}
virtual void Execute() = 0;
};
class ConcreteCommand1 :public Command
{
public:
ConcreteCommand1(Receiver* pReceiver) :Command(pReceiver){
}
virtual void Execute() {
m_pReceiver->Action1();
}
};
class ConcreteCommand2 :public Command
{
public:
ConcreteCommand2(Receiver* pReceiver) :Command(pReceiver){
}
virtual void Execute() {
m_pReceiver->Action2();
}
};
class Invoker
{
vector<Command*> m_commandList;
public:
~Invoker() {
auto it = m_commandList.begin();
while (it != m_commandList.end()) {
delete* it;
++it;
}
m_commandList.clear();
}
void AddCmd(Command* pCommand)
{
m_commandList.emplace_back(pCommand);
cout << "增加命令" << endl;
}
//通知执行
void Notify()
{
auto it = m_commandList.begin();
while (it != m_commandList.end())
{
(*it)->Execute();
++it;
}
}
};
#include "Command.h"
int main() {
Receiver* pReceiver = new Receiver();
Invoker *pInvoker = new Invoker();
pInvoker->AddCmd(new ConcreteCommand1(pReceiver));
pInvoker->AddCmd(new ConcreteCommand2(pReceiver));
pInvoker->Notify();
delete pInvoker;
delete pReceiver;
return 0;
}
运行结果:
6.1 请求者和接收者不直接打交道,而是通过命令对象(3.1)。
6.2 增加新命令ConcreteCommand3,不需要修改其它类(3.4)。