介绍
命令模式:将请求封装成对象,以便使用不同的请求、日志、队列等来参数化其他对象。命令模式也支持撤销操作。
参与者
- Command 声明执行操作的接口。
- ConcreteCommand 将一个接受者对象 绑定一个动作,调用接收着相应的操作,以实现excute。
- Client 创建一个具体命令并设定它的接收者。
- Invoker 存储具体的命令,执行用户的请求。
- Receiver 知道如何执行请求,就是实际的操作。
代码
class ReceiverA {//Receiver
public:
void doSomthing() {
std::cout<<"DO A"<<std::endl;
}
};
class ReceiverB {//Receiver
public:
void doSomthing() {
std::cout<<"DO B"<<std::endl;
}
};
class ICommand{//命令对象基类 Command
public:
virtual ~ICommand(){}
virtual void Execute() = 0;
};
class CommandA : public ICommand{//ConcreteCommand
public:
explicit CommandA(ReceiverA *a):rec(a){}
void Execute() override {
rec->doSomthing();
}
private:
ReceiverA *rec;
};
class CommandB : public ICommand{//ConcreteCommand
public:
explicit CommandB(ReceiverB *a):rec(a){}
void Execute() override {
rec->doSomthing();
}
private:
ReceiverB *rec;
};
class Invoker{//Invoker
public:
void Add(int index,ICommand *cmd){
command_m.insert(std::make_pair(index,cmd));
}
void Remove(int index){
command_m.erase(index);
}
void DoCmd(int i){
auto it = command_m.find(i);
if(command_m.end() != it)
{
it->second->Execute();
}
}
private:
std::map<int,ICommand *> command_m;
};
int main()//Client
{
Invoker invoker;
ICommand *cmd1 = new CommandA(new ReceiverA);
ICommand *cmd2 = new CommandB(new ReceiverB);
invoker.Add(1,cmd1);
invoker.Add(2,cmd2);
invoker.DoCmd(2);
invoker.DoCmd(1);
invoker.DoCmd(4);
invoker.DoCmd(2);
}
输出
DO B
DO A
DO B
特点
- 将调用命令的对象与和如何实现命令的对象解耦
- 增加新的Command很容易