C ++ design patterns - command mode
Reference URL: https: //blog.csdn.net/u012611878/article/details/77726460
Command Mode
In software design, we often need to send a request to certain objects, but does not know who is the recipient of the request, do not know what action is being requested, we only need to specify a specific request to the recipient that is when the program runs may, at this time, command mode can be used to design such a request sender and the request receiver to eliminate the coupling between each other, so that the calling relationships between objects more flexible.
Command mode can completely decouple senders and receivers, there is no direct reference to the relationship between the sender and the receiver, the object sends the request only need to know how to send requests without having to know how to complete the request. This is the command mode mode motive.
1. schema definition
Mode Command (Command Pattern): Encapsulate a request for an object, so that we can use a different parameterization to client requests; request queue or log requests, and support undoable operations. Command Mode is an object behavioral pattern, which is an alias for the action (Action) mode or transaction (Transaction) mode.
2. Mode Structure
Command mode contains the following roles:
Command: 抽象命令类
ConcreteCommand: 具体命令类
Invoker: 调用者
Receiver: 接收者
Client:客户类
FIG Command Mode Class
Command mode to achieve
#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;
}