當核心業務(如購票)完成後,需觸發「記錄日誌、發送簡訊、贈送優惠券、發放積分」等多項獨立邏輯。若直接在核心程式碼中硬編碼呼叫,會導致緊密耦合,維護困難。觀察者模式透過「主題註冊觀察者、事件發生時統一通知」實現鬆耦合,符合介面導向程式設計原則。
interface ITicketObserver { // 觀察者介面
public function onBuyTicketOver($sender, $args);
}
interface ITicketObservable { // 主題介面
public function addObserver($observer);
}
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;
}
}
// 簡訊日誌
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>";
}
}
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張。
HipiaoBuy。SplSubject/SplObserver 內建介面,提升標準化程度。stopPropagation())等進階機制。