介紹
??命令模式:將請求封裝成對象,以便使用不同的請求、日志阵面、隊(duì)列等來參數(shù)化其他對象。命令模式也支持撤銷操作洪鸭。
參與者
- Command 聲明執(zhí)行操作的接口样刷。
- ConcreteCommand 將一個接受者對象 綁定一個動作,調(diào)用接收著相應(yīng)的操作卿嘲,以實(shí)現(xiàn)excute颂斜。
- Client 創(chuàng)建一個具體命令并設(shè)定它的接收者。
- Invoker 存儲具體的命令拾枣,執(zhí)行用戶的請求沃疮。
- Receiver 知道如何執(zhí)行請求,就是實(shí)際的操作梅肤。
代碼
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
特點(diǎn)
- 將調(diào)用命令的對象與和如何實(shí)現(xiàn)命令的對象解耦
- 增加新的Command很容易
參考
- 《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》
- https://www.cnblogs.com/lzhp/p/3395320.html
- https://www.cnblogs.com/fxycm/p/4870636.html