極簡設計模式-命令模式

long2ge發表於2021-12-10

定義

將一個請求封裝為一個物件,從而讓我們可用不同的請求對客戶進行引數化;對請求排隊或者記錄請求日誌,以及支援可撤銷的操作。

設計的原則和思想

  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. 飯店點菜。每點的一道菜都是一個命令。
本作品採用《CC 協議》,轉載必須註明作者和本文連結
Long2Ge

相關文章