首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 設計模式實戰:命令模式封裝請求實現撤銷/隊列/日誌

     編輯:PHP 相關知識

命令模式將「請求」封裝為獨立對象,實現請求參數化、隊列化、日誌化、可撤銷操作。是 GUI 按鈕、異步任務、事務腳本的經典選擇。

核心角色

角色職責對應類
Command (命令接口)聲明 execute() 統一接口Command interface
ConcreteCommand (具體命令)綁定接收者與動作,實現 execute()LightOnCommand
Receiver (接收者)執行具體業務邏輯Light
Invoker (調用者/請求者)持有命令對象,觸發 execute()RemoteControl
Client (客戶端)創建命令、接收者、調用者並裝配腳本主程序

經典實現:智能家電遙控器

<?php
// 1. 命令接口
interface Command {
    public function execute();
    public function undo(); // 支持撤銷
}

// 2. 接收者:燈
class Light {
    private $location;
    public function __construct($location) { $this->location = $location; }
    public function on()  { echo "{$this->location} 燈已開啟\n"; }
    public function off() { echo "{$this->location} 燈已關閉\n"; }
}

// 3. 具體命令:開燈
class LightOnCommand implements Command {
    private $light;
    public function __construct(Light $light) { $this->light = $light; }
    public function execute() { $this->light->on(); }
    public function undo()      { $this->light->off(); }
}

// 4. 具體命令:關燈
class LightOffCommand implements Command {
    private $light;
    public function __construct(Light $light) { $this->light = $light; }
    public function execute() { $this->light->off(); }
    public function undo()      { $this->light->on(); }
}

// 5. 調用者:遙控器(支持撤銷、隊列)
class RemoteControl {
    private $onCommands = [];
    private $offCommands = [];
    private $lastCommand = null;
    private $history = []; // 命令隊列/日誌

    public function setCommand($slot, Command $onCmd, Command $offCmd) {
        $this->onCommands[$slot]  = $onCmd;
        $this->offCommands[$slot] = $offCmd;
    }

    public function onButtonPressed($slot) {
        $cmd = $this->onCommands[$slot];
        $cmd->execute();
        $this->lastCommand = $cmd;
        $this->history[] = ['cmd' => $cmd, 'time' => time(), 'type' => 'on'];
    }

    public function offButtonPressed($slot) {
        $cmd = $this->offCommands[$slot];
        $cmd->execute();
        $this->lastCommand = $cmd;
        $this->history[] = ['cmd' => $cmd, 'time' => time(), 'type' => 'off'];
    }

    public function undoButtonPressed() {
        if ($this->lastCommand) {
            $this->lastCommand->undo();
            $this->history[] = ['cmd' => $this->lastCommand, 'time' => time(), 'type' => 'undo'];
        }
    }

    public function getHistory() { return $this->history; }
}

// 6. 客戶端裝配
$livingRoomLight = new Light('客廳');
$kitchenLight    = new Light('廚房');

$remote = new RemoteControl();
$remote->setCommand(0, new LightOnCommand($livingRoomLight), new LightOffCommand($livingRoomLight));
$remote->setCommand(1, new LightOnCommand($kitchenLight),    new LightOffCommand($kitchenLight));

// 使用
$remote->onButtonPressed(0);  // 客廳 燈已開啟
$remote->offButtonPressed(0); // 客廳 燈已關閉
$remote->undoButtonPressed(); // 客廳 燈已開啟 (撤銷關閉)

// 查看日誌
print_r($remote->getHistory());

四大核心價值場景

  1. 參數化對象: 將行為作為參數傳遞、存儲、傳輸
  2. 隊列/調度: 命令對象可序列化存入隊列,異步執行(如 Laravel Jobs)
  3. 日誌/審計: 記錄命令執行歷史,支持回放、審計
  4. 撤銷/重做: 保存狀態或反向操作實現 undo()(文本編輯器、事務回滾)

進階擴展:宏命令(組合模式結合)

class MacroCommand implements Command {
    private $commands = [];
    public function add(Command $cmd) { $this->commands[] = $cmd; }
    public function execute() { foreach ($this->commands as $c) $c->execute(); }
    public function undo() { foreach (array_reverse($this->commands) as $c) $c->undo(); }
}

// 一鍵「離家模式」
$leaveHome = new MacroCommand();
$leaveHome->add(new LightOffCommand($livingRoomLight));
$leaveHome->add(new LightOffCommand($kitchenLight));
$leaveHome->add(new LockDoorCommand($frontDoor));
$leaveHome->add(new ArmAlarmCommand($alarm));

$remote->setCommand(9, $leaveHome, new MacroCommand()); // 撤銷需反向宏命令
$remote->onButtonPressed(9); // 依次執行所有關閉/鎖定/布防

現代框架中的應用

  • Laravel Jobs/Commands: 本質是命令模式,handle() 對應 execute()
  • Symfony Messenger: Command Bus 分發 Command 到 Handler
  • Redux/Vuex Action: 前端狀態管理的命令模式變體
  • 資料庫遷移: up()/down() 即 execute()/undo()

命令模式將「做什麼」與「誰做、何時做」解耦,是構建靈活、可測試、可擴展系統的基石模式之一。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved