命令模式--行为模式

1、描述

命令是一种行为设计模式,它可将请求或简单操作转换为一个对象。

此类转换让你能够延迟进行或远程执行请求,还可将其放入队列中。

优点:1、类间解耦--调用者角色与接收者之间没有任何依赖关系,调用者实现功能时只需调用Command抽象类的execute方法就可以,不需要了解到底是哪个接收者执行。2、可扩展性--Command的子类可以非常容易地扩展,而调用者Invoker和高层次的模块Client不产生严重的代码耦合。3、命令模式结合其他模式会更优秀

缺点:如果有N个命令,问题就出来了,Command的子类就不是几个,而是很多个,这个类膨胀得非常大

2、结构图

  • 发送者(Sender)--亦称“触发者(Invoker)”负责对请求进行初始化,其中必须包括一个成员变量来存储对于命令对象的引用。发送者触发命令,而不向接收者直接发送请求。注意,发送者并不负责创建命令对象:它通常通过构造函数从客户端处获得预先生成的命令。
  • 命令(Command)接口通常仅声明一个执行命令的方法。
  • 具体命令(Concrete Commands)会实现各种类型的请求。具体命令自身并不完成工作,而是会将调用委派给一个业务逻辑对象。但为了简化代码,这些类可以进行合并。接收对象执行方法所需的参数可以声明为具体命令的成员变量。你可以将命令对象设为不可变,仅允许通过构造函数对这些成员变量进行初始化。
  • 接收者(Receiver)类包含部分业务逻辑。几乎任何对象都可以作为接收者。绝大部分命令值处理如何将请求传递给接收者的细节,接收者自己完成实际的工作。
  • 客户端(Client)会创建并配置具体命令对象。客户端必须将包括接收者实体在内的所有请求参数传递给命令的构造函数。此后,生成的命令就可以与一个或多个发送者相关联了。

3、C++代码

#include <iostream>
#include <string>

//命令接口声明了一个执行命令的方法
class Command {
 public:
  virtual ~Command() {
  }
  virtual void Execute() const = 0;
};

//一些命令可以单独实现简单的操作
class SimpleCommand : public Command {
 private:
  std::string pay_load_;

 public:
  explicit SimpleCommand(std::string pay_load) : pay_load_(pay_load) {
  }
  void Execute() const override {
    std::cout << "SimpleCommand: See, I can do simple things like printing (" << this->pay_load_ << ")\n";
  }
};

//Receiver类包含一些重要的业务逻辑。他们知道如何执行与请求相关的各种操作。
//事实上,任何类都可以成为一个Recviver
class Receiver {
 public:
  void DoSomething(const std::string &a) {
    std::cout << "Receiver: Working on (" << a << ".)\n";
  }
  void DoSomethingElse(const std::string &b) {
    std::cout << "Receiver: Also working on (" << b << ".)\n";
  }
};

//一些命令可以向其他对象分派更复杂的操作,这些对象成为接收者
class ComplexCommand : public Command {
  
 private:
  Receiver *receiver_;
  //上下文数据,用于启动接收器的方法。
  std::string a_;
  std::string b_;
  
  //通过构造函数,复杂的命令可以获取一个或多个接收者对象以及相关的上下文数据 
 public:
  ComplexCommand(Receiver *receiver, std::string a, std::string b) : receiver_(receiver), a_(a), b_(b) {
  }
  
  void Execute() const override {
    std::cout << "ComplexCommand: Complex stuff should be done by a receiver object.\n";
    this->receiver_->DoSomething(this->a_);
    this->receiver_->DoSomethingElse(this->b_);
  }
};


//发送者 (Sender)——亦称 “触发者 (Invoker)”
//与一个或多个命令对象关联。它向命令发送一个请求
class Invoker {

 private:
  Command *on_start_;

  Command *on_finish_;

 public:
  ~Invoker() {
    delete on_start_;
    delete on_finish_;
  }

  void SetOnStart(Command *command) {
    this->on_start_ = command;
  }
  void SetOnFinish(Command *command) {
    this->on_finish_ = command;
  }
  
  //Invoker并不依赖具体的命令类或接收者类。它通过执行一个命令间接向接收者类传递一个请求。
  void DoSomethingImportant() {
    std::cout << "Invoker: Does anybody want something done before I begin?\n";
    if (this->on_start_) {
      this->on_start_->Execute();
    }
    std::cout << "Invoker: ...doing something really important...\n";
    std::cout << "Invoker: Does anybody want something done after I finish?\n";
    if (this->on_finish_) {
      this->on_finish_->Execute();
    }
  }
};

//客户端代码可以用任何命令参数化调用程序。
int main() {
  Invoker *invoker = new Invoker;
  invoker->SetOnStart(new SimpleCommand("Say Hi!"));
  Receiver *receiver = new Receiver;
  invoker->SetOnFinish(new ComplexCommand(receiver, "Send email", "Save report"));
  invoker->DoSomethingImportant();

  delete invoker;
  delete receiver;

  return 0;
}

参考

https://refactoringguru.cn/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值