萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> PHP 程式設計

PHP 觀察者模式實戰:解耦購票後續業務邏輯

前言

當核心業務(如購票)完成後,需觸發「記錄日誌、發送簡訊、贈送優惠券、發放積分」等多項獨立邏輯。若直接在核心程式碼中硬編碼呼叫,會導致緊密耦合,維護困難。觀察者模式透過「主題註冊觀察者、事件發生時統一通知」實現鬆耦合,符合介面導向程式設計原則。

場景描述

  • 核心:購票流程
  • 衍生邏輯:文字日誌、資料庫日誌、發送簡訊、贈送抵扣券/兌換券/積分、各類活動
  • 痛點:每新增一項邏輯都要修改核心類別,違反開放封閉原則

程式碼實作

1. 定義介面

interface ITicketObserver {  // 觀察者介面
    public function onBuyTicketOver($sender, $args);
}

interface ITicketObservable {  // 主題介面
    public function addObserver($observer);
}

2. 主題類別(購票核心)

class HipiaoBuy implements ITicketObservable {
    private $_observers = [];

    public function buyTicket($ticket) {
        // TODO: 核心購票邏輯
        // 完成後通知所有觀察者
        foreach ($this->_observers as $obs) {
            $obs->onBuyTicketOver($this, $ticket);
        }
    }

    public function addObserver($observer) {
        $this->_observers[] = $observer;
    }
}

3. 具體觀察者

// 簡訊日誌
class HipiaoMSM implements ITicketObserver {
    public function onBuyTicketOver($sender, $ticket) {
        echo date('Y-m-d H:i:s') . " 簡訊日誌記錄:購票成功:$ticket<br>";
    }
}

// 文字日誌
class HipiaoTxt implements ITicketObserver {
    public function onBuyTicketOver($sender, $ticket) {
        echo date('Y-m-d H:i:s') . " 文字日誌記錄:購票成功:$ticket<br>";
    }
}

// 贈送抵扣券
class HipiaoDiKou implements ITicketObserver {
    public function onBuyTicketOver($sender, $ticket) {
        echo date('Y-m-d H:i:s') . " 贈送抵扣券:購票成功:$ticket 贈送10元抵扣券1張。<br>";
    }
}

4. 客戶端使用

date_default_timezone_set('PRC');

$buy = new HipiaoBuy();
$buy->addObserver(new HipiaoMSM());
$buy->addObserver(new HipiaoTxt());
$buy->addObserver(new HipiaoDiKou());

$buy->buyTicket('一排一號');

執行結果

2017-02-03 10:25:45 簡訊日誌記錄:購票成功:一排一號
2017-02-03 10:25:45 文字日誌記錄:購票成功:一排一號
2017-02-03 10:25:45 贈送抵扣券:購票成功:一排一號 贈送10元抵扣券1張。

優點總結

  1. 開放封閉:新增觀察者無需修改 HipiaoBuy。
  2. 單一職責:每個觀察者只處理自己的業務。
  3. 可測試性:可單獨測試各觀察者,或用 Mock 物件驗證通知機制。
  4. 動態組合:執行期決定掛載哪些觀察者,支援多租戶、A/B 測試等場景。

延伸建議

  • 引入 SplSubject/SplObserver 內建介面,提升標準化程度。
  • 若觀察者執行耗時,可改為非同步佇列(如 RabbitMQ、Redis List)由 Worker 消費。
  • 加入事件優先級、停止傳播(stopPropagation())等進階機制。
copyright © 萬盛學電腦網 all rights reserved