設計模式之觀察者模式

一.定義

觀察者模式 定義了對象之間的一對多的依賴關係,當某一個對象改變時候 ,它的所有依賴者都會收到通知並自動更新

有時又被稱爲發佈(publish )-訂閱(Subscribe)模式、模型-視圖(View)模式、源-收聽者(Listener)模式或從屬者模式)是軟件設計模式的一種

二. 使用場景

購票、訂閱報紙、訂閱牛奶等 當主題類某個業務邏輯發生時通知觀察者對象,每個觀察者執行自己的業務邏輯。

三.觀察者要素 

要有被觀察的接口(被觀察者) 和 被通知對象(觀察者)  

三觀察者思想的優缺點

觀察者模式的優點:

1.在觀察者和被觀察者之間建立了一個抽象的鬆耦合

2.觀察者模式支持廣播通訊,被觀察者會像所有的觀察者發生通知

觀察者模式的缺點:

1.如果一個被觀察者對象有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會花費很多時間。

2.如果在被觀察者之間有循環依賴的話,被觀察者會觸發它們之間進行循環調用,導致系統崩潰。在使用觀察者模式是要特別注意這一點。

3.如果對觀察者的通知是通過另外的線程進行異步投遞的話,系統必須保證投遞是以自恰的方式進行的。

4.雖然觀察者模式可以隨時使觀察者知道所觀察的對象發生了變化,但是觀察者模式沒有相應的機制使觀察者知道所觀察的對象是怎麼發生變化的。

四代碼說明

本代碼是本人原創 用觀察者模式思想實現氣象站 的功能  

<?php
<?php
/**
 * Created by PhpStorm.
 * User: guochunyan
 * Date: 2017/3/18
 * Time: 14:12
 * 觀察者模式:
 * 定義:
 *  觀察者模式典型實現方式(拿天氣預報舉例):
 * 1、定義2個接口:觀察者(通知)接口、被觀察者(主題)接口
 * 2、定義2個類,觀察者對象實現觀察者接口、主題類實現被觀者接口
 * 3、創建天氣預報對象(被觀察者)
 * 4、創建一個觀察者 && 加入觀察者隊列中
 * 5、數據變化調用setmeasurementsChanged 通知觀察者
 *
 * 應用場景:購票、訂閱報紙、訂閱牛奶
 */
//主題 類
class weatherData implements subject {
    private   $_observer  = array();
    private   $_temperature = 0 ;
    private   $_humidity    = 0 ;
    private   $_presssure   = 0 ;
    //增加 觀察者
    public function  registerObserver($observer){
        //這裏需要增加去重機制----
        $this->_observer[] = $observer;
    }
    //移除 觀察者
    public function  removeObserver($observer){
        unset($this->_observer[$observer]);
        if(!empty($this->_observer)){
            foreach ($this->_observer as $key =>  $observers){
                if($observer == $observers){
                    unset($this->_observer[$key]);
                    continue;
                }
            }
        }
    }
    //通知 觀察者
    public function  notifyObserver(){
        if(!empty($this->_observer)){
            foreach ($this->_observer as  $observer){
                $observer->update();
            }
        }
    }
    //調用 更改
    public function  measurementsChanged(){
        $this->notifyObserver();
    }
    //通知 接口
    public function setmeasurementsChanged($tmp, $hum, $pre){
        $this->_temperature = $tmp;
        $this->_humidity    = $hum;
        $this->_presssure   = $pre;
        $this->measurementsChanged();
    }

}
//觀察者 類
class obj implements Observer{
    public function  update($temp, $hum, $pres){
        echo "溫度:".$temp."  溼度:".$hum."  氣壓: ".$pres;
    }
}
//主題接口
interface subject{
    public function  registerObserver($observer);
    public function  removeObserver($observer);
    public function notifyObserver();
}
//觀察者接口
interface Observer{
    public function update($temp, $hum, $pres);
}

//創建一個天氣預報
$date = new weatherData();
//生成觀察者$obj_p
$obj_p = new obj();
//把$obj_p 放在天氣預報 的被通知名單
$date->registerObserver($obj_p);
//氣象系統有數據更新
$date->setmeasurementsChanged(10,30,49);


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