C++ 设计模式-命令模式
参考网址:https://blog.csdn.net/u012611878/article/details/77726460
命令模式
在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活。
命令模式可以对发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。这就是命令模式的模式动机。
1.模式定义
命令模式(Command Pattern):将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。命令模式是一种对象行为型模式,其别名为动作(Action)模式或事务(Transaction)模式。
2.模式结构
命令模式包含如下角色:
Command: 抽象命令类
ConcreteCommand: 具体命令类
Invoker: 调用者
Receiver: 接收者
Client:客户类
命令模式类图
命令模式实现
#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>
using namespace std;
/*-------------------------------------*/
class Receiver{
public:
Receiver()= default;
virtual ~Receiver() = default;
virtual void Action() = 0;
};
class Command{
public:
Command() = default;
virtual ~Command() = default;
virtual void Execute() = 0;
};
/*-------------------------------------*/
class ReceiverA : public Receiver{
public:
ReceiverA() = default;
~ReceiverA() override = default;
void Action() override {
cout << "receiverA action." << endl;
}
};
class ReceiverB : public Receiver{
public:
ReceiverB() = default;
~ReceiverB() override = default;
void Action() override {
cout << "receiverB action." << endl;
}
};
class ConcreteCommandA : public Command{
public:
ConcreteCommandA(std::unique_ptr<Receiver>&& receiver):mReceiver(std::move(receiver)){};
~ConcreteCommandA() override{std::cout<<"~ConcreteCommandA()"<<std::endl;};
void Execute() override {
cout << "ConcreteCommandA::execute" << endl;
mReceiver->Action();
}
private:
std::unique_ptr<Receiver> mReceiver = nullptr;
};
class ConcreteCommandB : public Command{
public:
ConcreteCommandB(std::unique_ptr<Receiver>&& receiver):mReceiver(std::move(receiver)){};
~ConcreteCommandB() override {std::cout<<"~ConcreteCommandB()"<<std::endl;};;
void Execute() override {
cout << "ConcreteCommandB::execute" << endl;
mReceiver->Action();
}
private:
std::unique_ptr<Receiver> mReceiver = nullptr;
};
/*-------------------------------------*/
class Invoker{
public:
Invoker() = default;
~Invoker()= default;
public:
void AddCommand(std::unique_ptr<Command>&& command){
mCommandList.emplace_back(std::move(command));
}
void ClearCommand(){
mCommandList.clear();
}
void Call() {
cout << "invoker calling" << endl;
for_each(mCommandList.begin(),mCommandList.end(),[](std::unique_ptr<Command>& command){command->Execute();});
}
private:
std::vector<unique_ptr<Command>> mCommandList;
};
int main(){
{
std::unique_ptr<Receiver> receiverA(new ReceiverA());
std::unique_ptr<Receiver> receiverB(new ReceiverB());
std::unique_ptr<Invoker> invoker (new Invoker());
std::unique_ptr<Command> commandA (new ConcreteCommandA(std::move(receiverA)));
std::unique_ptr<Command> commandB (new ConcreteCommandB(std::move(receiverB)));
invoker->AddCommand(std::move(commandA));
invoker->AddCommand(std::move(commandB));
invoker->Call();
invoker->ClearCommand();
}
return 0;
}