命令模式 Command Pattern

未匹配的标注

定义

将一个请求封装为一个对象,从而让我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。

设计的原则和思想

  1. 解耦的是行为请求(发起)者和行为实现(执行)者。
  2. 不变部分是行为实现者,变化部分是行为请求者。
  3. 核心思想是将函数封装成命令对象。

一句话概括设计模式

调用者通过命令类让接受者执行指令。

结构中包含的角色

  1. Command(抽象命令类)
  2. ConcreteCommand(具体命令类)
  3. Invoker(调用者,行为请求者,动作的发起者)
  4. Receiver(接收者,行为实现者,动作的承受者)

最小可表达代码

// 接收者
class Receiver
{
  public function action()
  {
    echo '执行命令的具体逻辑';
  }
}

// 抽象命令类
interface Command
{
  public function execute();
}

// 具体命令类
class ConcreteCommand implements Command
{
  private $receiver;

  public function __construct()
  {
    $this->receiver = new Receiver();
  }

  public function execute()
  {
    $this->receiver->action();
  }
}

// 调用者
class Invoker
{
  private $command;

  public function __construct(Command $command)
  {
    $this->command = $command;
  }

  public function call()
  {
    $this->command->execute();
  }
}

$invoker = new Invoker(new ConcreteCommand());
$invoker->call();

优点

  1. 在不修改代码的情况下创建新的命令。
  2. 实现操作的延迟执行。
  3. 命令可以相互组合,组合一个复杂命令。
  4. 一个命令对象和请求的初始调用者可以有不同的生命期。
  5. 可以控制命令的执行流程。异步、延迟、排队执行命令、撤销重做命令、存储命令等。

缺点

  1. 代码会变得更加复杂。
  2. 命令模式是为了松耦合。如果调用者或者具体命令类增多,维护性都会降低。

何时使用

  1. 需要将请求调用者和请求接收者解耦。
  2. 某些请求需要延迟执行。可以将请求写入队列,然后延迟执行队列。
  3. 将特定的方法调用转化为对象。

实际应用场景

  1. 操作回滚功能。备忘录模式可能会占用大量内存。命令模式就是反向操作。
  2. 实现队列。将命令类序列化放入队列中,然后执行。
  3. 电脑开机。开机键就是一个命令。
  4. 饭店点菜。每点的一道菜都是一个命令。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
发起讨论 只看当前版本


暂无话题~