第六節 PHP設計模式(五)—觀察者模式 (observer Pattern)

觀察者模式 (observer Pattern): 定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新。也叫發佈-訂閱模式

(一)爲什麼需要觀察者模式

1,一個對象狀態改變給其他對象通知的問題,而且要考慮到易用和低耦合,保證高度的協作

2,完美的將觀察者和被觀察的對象分離開,使得每個類將重點放在某一個功能上,一個對象只做一件事情。

3,觀察者模式在模塊之間劃定了清晰的界限,提高了應用程序的可維護性和重用性

(二)觀察者模式 UML圖
 這個設計模式的UML圖比較全

(三)簡單實例

觀察者模式也叫發佈訂閱模式,如果說我們現在在做一個系統。我們讓所有客戶端訂閱我們的服務端,那麼當我們的服務端有更新信息的時候,就通知客戶端去更新。這裏的服務端就是被觀察者,客戶端就是觀察者。

對於PHP來說觀察者的另一種實現方式,是通過實現SplSubject接口和SplObserver,這種實現方法涉及到spl(standard php library)的內容,這裏僅僅演示如何實現,具體的大家可以自行google||百度。

abstract class Entity{
    private $observers = [];

    public function add($observer)
    {
        // 注意 直接把對象作爲字符串輸出的話,會調用魔術方法__toString
        $this->observers[] = $observer;
        echo sprintf("%s觀察者添加成功!<br/>", $observer);
    }

    public function delete($observer)
    {
        $key = array_search($observer, $this->observers);
        // 對象存在但是不一定是同一個對象,所以需要 === 判斷一下
        if ($observer === $this->observers[$key]){
            unset($this->observers[$key]);
            echo sprintf("觀察者刪除成功!<br/>");
        }else{
            echo sprintf("觀察者不存在!<br/>");
        }
    }

    public function notifyObserver()
    {
        foreach ($this->observers as $observer){
            $observer->save();
        }
    }
}

class server extends Entity{
    public function publish()
    {
        echo sprintf("618就要到了,活動福利多多請關注<br/>");
        $this->notifyObserver();
    }
}

Interface Observer{
    public function save();
}

class Wechat implements Observer{
    public function save()
    {
        echo sprintf("%s已經發送了!<br/>", __CLASS__);
    }
    // object to string 時調用
    public function __toString()
    {
        return __CLASS__;
    }
}
class Android implements Observer{
    public function save()
    {
        echo sprintf("%s已經發送了!<br/>", __CLASS__);
    }
    // object to string 時調用
    public function __toString()
    {
        return __CLASS__;
    }
}
class Ios implements Observer{
    public function save()
    {
        echo sprintf("%s已經發送了!<br/>", __CLASS__);
    }
    // object to string 時調用
    public function __toString()
    {
        return __CLASS__;
    }
}

// 實例化被觀察者
$entity = new Server();
// 註冊微信
$entity->add(new Wechat());
// 註冊安卓
$entity->add(new Android());
$ios = new Ios();
// 註冊IOS
$entity->add($ios);
// 觸發時間,發送消息
$entity->publish();
//輸出信息如下
//Wechat觀察者添加成功!
//Android觀察者添加成功!
//Ios觀察者添加成功!
//618就要到了,活動福利多多請關注
//Wechat已經發送了!
//Android已經發送了!
//Ios已經發送了!

// 新實例化IOS 然後刪除IOS
$entity->delete(new Ios()); // 會提示 觀察者不存在!
// 再次發消息
$entity->publish();


// 刪除IOS
$entity->delete($ios);
// 再次發消息
$entity->publish();
//輸出信息如下
// ………………
//觀察者刪除成功!
//618就要到了,活動福利多多請關注
//Wechat已經發送了!
//Android已經發送了!

參考資料:

https://design-patterns.readthedocs.io

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章