命令模式 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 网站上。

上一篇 下一篇
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 0
发起讨论 查看所有版本


暂无话题~