【设计模式】命令模式

命令模式是一种行为设计模式。将一系列操作,封装为类(命令),使用队列保存历史命令,实现撤销undo操作。

  • Command:抽象命令类。
  • ConcreteCommand:具体命令类,依赖Receiver类执行不同命令。
  • Invoker:调用者类,持有命令队列,触发命令。
  • Receiver:concreteCommand操作的对象,执行具体的命令。
  • Client:调用Invoker触发命令。
#include <iostream>
#include <stack>
#include <memory>

//底层执行
class Receiver
{
public:
    Receiver()=default;
    ~Receiver()=default;
    Receiver(const Receiver& another)
    {
       this->str_ = another.str_; 
    }
    Receiver& operator=(Receiver& another)
    {
        if(&another==this)
            return *this;
       this->str_ = another.str_; 
       return *this;
    }
    Receiver(Receiver&& another)
    {
       this->str_ = std::move(another.str_);
    }
    Receiver& operator=(Receiver&& another)
    {
        if(&another==this)
            return *this;
       this->str_ = std::move(another.str_);
       return *this;
    }
    std::string Do()const  {return str_;}
private:
    std::string str_{"do something..\n"};
};

class Command
{
public:
    Command()=default;
    virtual ~Command()=default;
    virtual void Execute()=0;
    virtual void Undo()=0;
};

//封装底层执行,暴露命令或操作
class PasteCommand:public Command
{
public:
    PasteCommand(Receiver receiver)
    {
        receiver_ = std::move(receiver);
    }
    virtual void Execute()override  { std::cout<<receiver_.Do()<<"\n";}
    virtual void Undo()override  {std::cout<<"un"<<receiver_.Do()<<"\n";}
private:
    Receiver receiver_;
};

//记录历史操作。触发操作、undo操作。
class Invoker
{
public:
    //通过SetCommand进行依赖注入(或改为构造)
    void SetCommand(std::unique_ptr<Command> command)
    {
        this->command_ = std::move(command);
    }
    void Click()
    {
        command_->Execute();
        history_.push(std::move(command_));
    }
    void Undo()
    {
        auto last = std::move(history_.top());
        last->Undo();
        history_.pop();
    }
private:
    std::unique_ptr<Command> command_{nullptr};
    std::stack<std::unique_ptr<Command>> history_;
};

int main()
{
    Receiver receiver;
    std::unique_ptr<Command> upc = std::make_unique<PasteCommand>(receiver);
    Invoker invoker;
    invoker.SetCommand(std::move(upc)); 
    invoker.Click();
    invoker.Undo();
    return 0;
}
posted @ 2026-05-05 18:19  仰望星河Leon  阅读(12)  评论(0)    收藏  举报