天天看點

PHP常用設計模式:觀察者模式

觀察者模式當對象間存在一對多關系時,則使用觀察者模式。當一個對象的狀态發生改變時,所有依賴于它的對象都得到通知并被自動更新

優點: 1、觀察者和被觀察者是抽象耦合的。 2、建立一套觸發機制。

缺點: 1、如果一個被觀察者對象有很多的直接和間接的觀察者的話,将所有的觀察者都通知到會花費很多時間。 2、如果在觀察者和觀察目标之間有循環依賴的話,觀察目标會觸發它們之間進行循環調用,可能導緻系統崩潰。 3、觀察者模式沒有相應的機制讓觀察者知道所觀察的目标對象是怎麼發生變化的,而僅僅隻是知道觀察目标發生了變化。

在php中,SplObserver接口與SplSubject一起使用以實作觀察者設計模式。

例:如一個使用者上線後,通知他的好友并給他推送消息

<?php
//觀察者1号,好友
class Friends implements SplObserver {
    //接收被觀者的更新通知
    public function update(SplSubject $subject) {
        echo "你的好友".$subject->name."上線了!";
    }
}
//觀察者二号
class PushMsg implements SplObserver {
    public function update(SplSubject $subject) {
        echo "hello,",$subject->name;
    }
}
//被觀察者,使用者
class User implements SplSubject {
    private $_observers;
    public $name;

    public function __construct($name) {
        //SplObjectStorage類提供了從對象到資料的映射,或者通過忽略資料,提供了一個對象集
        $this->_observers = new SplObjectStorage();
        $this->name = $name;
    }
    //新來一個觀察者
    public function attach(SplObserver $observer) {
        $this->_observers->attach($observer);
    }
    //離開了一個觀察者
    public function detach(SplObserver $observer) {
        $this->_observers->detach($observer);
    }
    //通知觀察者
    public function notify() {
        foreach ($this->_observers as $observer) {
            $observer->update($this);
        }
    }

    public function login() {
        $this->notify();
    }
}

$observer1= new Friends();
$observer2=new PushMsg();
$user=new User('小明');
$user->attach($observer1);
$user->attach($observer2);
$user->login();