命令模式
Command(抽象命令类):抽象出命令对象,可以根据不同的命令类型。写出不同的实现类
Concrete Command(具体命令类):实现了抽象命令对象的具体实现
Invoker(调用者/请求者):请求的发送者,它通过命令对象来执行请求。一个调用者并不需要在设计时确定其接收者,因此它只与抽象命令来之间存在关联。在程序运行时,将调用命令对象的execute() ,间接调用接收者的相关操作。
Receiver(接收者):接收者执行与请求相关的操作,真正执行命令的对象。具体实现对请求的业务处理。未抽象前,实际执行操作内容的对象。
Client(客户端):在客户类中需要创建调用者对象,具体命令类对象,在创建具体命令对象时指定对应的接收者。发送者和接收者之间没有之间关系。都通过命令对象来调用。
示例:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <typeinfo>
using namespace std;
// 接受者,作为最底层的调用
class Receiver
{
public:
void BakeMutton()
{
cout << "烤羊肉" << endl;
}
void BakeChicken()
{
cout << "烤鸡翅" << endl;
}
};
// 基类
class Command
{
public:
Command(Receiver* pstReceiver) :m_pstReceiver(pstReceiver)
{
}
virtual void Excute() = 0;
protected:
Receiver* m_pstReceiver;
};
// 具体类,用于调用接收者
class ConcreteCommandA : public Command
{
public:
ConcreteCommandA(Receiver* pstReceiver) :Command(pstReceiver)
{
}
virtual void Excute()
{
cout << "ConcreteCommandA excuting......" << endl;
m_pstReceiver->BakeMutton();
}
};
// 具体类,用于调用接收者
class ConcreteCommandB : public Command
{
public:
ConcreteCommandB(Receiver* pstReceiver) :Command(pstReceiver)
{
}
virtual void Excute()
{
cout << "ConcreteCommandB excuting......" << endl;
m_pstReceiver->BakeChicken();
}
};
// 调用者,作为最上层,用于管理具体类的操作,从而对接收者增删
class Invoke
{
public:
void Add(Command* pstCommand)
{
m_vecPstCommand.push_back(pstCommand);
}
void Remove(Command* pstCommand)
{
m_vecPstCommand.erase(find(m_vecPstCommand.begin(), m_vecPstCommand.end(), pstCommand));
}
void RemoveAll()
{
m_vecPstCommand.clear();
}
void Notify()
{
for (vector<Command*>::iterator it = m_vecPstCommand.begin(); it != m_vecPstCommand.end(); ++it)
//for (typeof(m_vecPstCommand.begin()) it = m_vecPstCommand.begin(); it != m_vecPstCommand.end(); ++it)
{
(*it)->Excute();
}
}
private:
vector<Command*> m_vecPstCommand;
};
int main(int argc, char* argv[])
{
Receiver* pstReceiver = new Receiver();
Command* pstConcreteCommandA = new ConcreteCommandA(pstReceiver);
Command* pstConcreteCommandB = new ConcreteCommandB(pstReceiver);
Invoke* pstInvoke = new Invoke();
pstInvoke->Add(pstConcreteCommandA);
pstInvoke->Add(pstConcreteCommandA);
pstInvoke->Add(pstConcreteCommandB);
pstInvoke->Notify();
cout << "------------------" << endl << endl;
pstInvoke->Remove(pstConcreteCommandA); //撤销操作
pstInvoke->Remove(pstConcreteCommandB);
pstInvoke->Notify();
cout << "------------------" << endl << endl;
getchar();
return 0;
}
/**
ConcreteCommandA excuting......
烤羊肉
ConcreteCommandA excuting......
烤羊肉
ConcreteCommandB excuting......
烤鸡翅
------------------
ConcreteCommandA excuting......
烤羊肉
------------------
**/
输出:
ConcreteCommandA excuting......
烤羊肉
ConcreteCommandA excuting......
烤羊肉
ConcreteCommandB excuting......
烤鸡翅
------------------
ConcreteCommandA excuting......
烤羊肉
------------------
参考:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了