C ++ design patterns - command mode

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

Here Insert Picture Description

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;
}
Published 155 original articles · won praise 15 · views 160 000 +

Guess you like

Origin blog.csdn.net/wangdamingll/article/details/104697865