• 第三章:千里眼顺风耳 - 观察者模式

    第三章:千里眼顺风耳 - 观察者模式

    武林秘籍

    在编程江湖中,有一门绝世武功名为"千里眼顺风耳",能够洞察千里之外,听闻八方动静。

    而在设计模式中,有一门与之对应的绝学——观察者模式

    何为观察者?

    观察者模式,就是定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会得到通知并自动更新。

    就像武林中的情报网络,一个消息传出,各方势力立即知晓。

    武功心法

    <?php
    /**
     * 千里眼顺风耳 - 观察者模式
     * 眼观六路,耳听八方
     */
    
    // 观察者接口
    interface Observer {
        public function update($subject);
    }
    
    // 主题接口
    interface Subject {
        public function attach(Observer $observer);
        public function detach(Observer $observer);
        public function notify();
    }
    
    // 武林盟主(具体主题)
    class MartialArtsAlliance implements Subject {
        private $observers = [];
        private $message;
        
        public function attach(Observer $observer) {
            $this->observers[] = $observer;
            echo "✅ 添加观察者:{$observer->getName()}\n";
        }
        
        public function detach(Observer $observer) {
            foreach ($this->observers as $key => $obs) {
                if ($obs === $observer) {
                    unset($this->observers[$key]);
                    echo "✅ 移除观察者:{$observer->getName()}\n";
                }
            }
        }
        
        public function notify() {
            echo "\n📢 武林盟主发布消息:{$this->message}\n";
            foreach ($this->observers as $observer) {
                $observer->update($this);
            }
        }
        
        public function setMessage($message) {
            $this->message = $message;
            $this->notify();
        }
        
        public function getMessage() {
            return $this->message;
        }
    }
    
    // 各派掌门(具体观察者)
    class SectLeader implements Observer {
        private $name;
        
        public function __construct($name) {
            $this->name = $name;
        }
        
        public function getName() {
            return $this->name;
        }
        
        public function update($subject) {
            $message = $subject->getMessage();
            echo "  → {$this->name} 收到消息:{$message}\n";
        }
    }
    
    // 使用示例
    echo "=== 千里眼顺风耳 - 观察者模式示例 ===\n";
    
    // 创建武林盟主
    $alliance = new MartialArtsAlliance();
    
    // 创建各派掌门
    $shaolin = new SectLeader("少林派");
    $wudang = new SectLeader("武当派");
    $emei = new SectLeader("峨眉派");
    
    // 添加观察者
    $alliance->attach($shaolin);
    $alliance->attach($wudang);
    $alliance->attach($emei);
    
    // 盟主发布消息
    $alliance->setMessage("明日午时,华山之巅,武林大会!");
    
    // 移除一个观察者
    $alliance->detach($wudang);
    
    // 再次发布消息
    $alliance->setMessage("紧急通知:魔教来袭,各派速来支援!");
    ?>
    

    江湖应用

    1. 事件处理 - 如同武林中的信号传递
    2. 消息推送 - 如同武林中的飞鸽传书
    3. 状态同步 - 如同武林中的号令传达

    千里眼顺风耳要诀

    • 眼观六路,耳听八方:一个主题,多个观察者
    • 一呼百应:主题状态改变,观察者立即响应
    • 松耦合:主题与观察者之间解耦,易于扩展

    修炼要点

    1. 观察者接口:定义统一的更新接口
    2. 主题接口:定义添加、移除、通知观察者的方法
    3. 具体实现:实现具体主题和观察者

    下回预告:第四章:分身术 - 原型模式

    本文章由设计模式武侠传系列发布