首頁  >  文章  >  後端開發  >  詳解PHP設計模式之觀察者模式

詳解PHP設計模式之觀察者模式

巴扎黑
巴扎黑原創
2017-08-17 09:05:131423瀏覽


摘要:Yii2的事件採用了“觀察者模式”,先了解觀察者,再學事件就容易了。

它是什麼

首先不要被名字所嚇倒,往下看,它真的很簡單。

先來一個比較高大上的定義:觀察者模式定義了一系列物件之間的一對多關係,當一個物件改變狀態後,其他依賴者都會收到通知。

看明白了麼?

如果沒明白我們再來一個生活一點的:觀察者模式就是訂報紙的模式,你和一些人向某個報社訂報紙,只要有新報紙出版,報社就會給你們送來,具體你們怎麼看和報社無關,只要報社不倒閉,就會一直送你們。

當然,你也可以取消訂閱。

觀察者模式== 報社+ 訂報紙的人

#無論你明白了哪種定義,記住一點,「觀察者模式」最屌的地方就是讓一些彼此依賴的類松耦合,牛逼的系統是什麼樣的?那就是每個物件間的依賴程度降到冰點,但依然可以互動。

Code it

我想到此刻,你已經清楚了觀察者模式,但是作為一個語言類文章,不寫點程式碼總說不過去,我們接下來用程式碼來實現上面的需求。

我們先來一個不用觀察者模式的程式碼

class Video {    public function new(){
        $checkNewVideo = Video::find()->where("xxxxx")->one();        if($checkNewVideo){            //    通知各位
            LaoWang::newVideo();
            XiaoLi::newVideo();
            ChuanPu::newVideo();
            .......            //    还有很多很多,比如在给某个集体客户群发、短信发等等等等
        }
    }
}//    具体实现$model = new Video();
$model->new();

其實,在系統小的時候,這是非常快速有效的方式。

但是,當系統變大的時候,這種方法馬上面臨難以擴展的問題,並且容易出錯。

  • 例如老王不想訂閱了,我們需要改原始碼。

  • 例如又增加了一個客戶,我們要去改原始碼。

  • 例如xxx,我們都需要改原始碼。

這兩個物件的耦合度太高了。

解決它- 用觀察者模式

我們先改進上面的程式碼

/**
 * 被观察者接口
 * 定义了一些公用方法声明,使用观察者模式的类都可以继承此接口
 */interface Observable {    // 添加/注册观察者
    public function attach(Observer $observer);    // 删除观察者
    public function detach(Observer $observer);    // 触发通知
    public function notify();
}class Video implements Observable {    public $observers = [];//    订阅者

    //    添加观察者
    public function attach(Observer $observer){
        $key = array_search($observer, $this->observers);        if ($key === false) {            $this->observers[] = $observer;
        }
    }    //    删除观察者
    public function detach(Observer $observer){
        $key = array_search($observer, $this->observers);        if ($key !== false) {            unset($this->observers[$key]);
        }
    }    //    通知所有观察者
    public function notify(){        foreach ($this->observers as $observer) {            // 把本类对象传给观察者
            $observer->update($this);
        }
    }    public function  new(){
        $checkNewVideo = Video::find()->where("xxxxx")->one();        if($checkNewVideo){            $this->notify();
        }
    }
}

你看到了,修改後的程式碼並不關心具體發送給誰,它只是遍歷了所有觀察者的列表,然後告訴他們一下而已,觀察者增減對此類不會有任何影響。

对于观察者,数字不定,随时有增减,因此我们定义了一个观察者接口开始抽象它们。

/**
 * 观察者接口
 */interface Observer{    // 接收到通知的处理方法
    public function update(Observable $observable);
}

老王、小明、川普、冰冰订阅了视频

class LaoWang implements Observer {    public function update(Observable $observable){        echo "立刻开始看视频";
    }
}class XiaoMing implements Observer {    public function update(Observable $observable){        echo "收到后忽略通知";
    }
}class ChuanPu implements Observer {    public function update(Observable $observable){        echo "收藏了一下,然后去wc看";
    }
}class BingBing implements Observer {    public function update(Observable $observable){        echo "立刻开始看视频";
    }
}

具体实现

$model = new Video();
$model->attach(new LaoWang());
$model->attach(new XiaoLi());
$model->attach(new ChuanPu());
$model->attach(new BingBing());
$model->new();

这样当我们再增加一个人加入 习大大 的时候,我们只需要增加一个习大大的观察者类,在实现的时候添加注册,而不需要去改Video类和其他的观察者类,将类之间的耦合降低了很多。

回头看

上面就是观察者模式,我们先预想一下我们的事件,假设我们定义了很多观察者代码,他们监听事件的发生,当一个事件被触发,这些观察者都会知道,执行各自的逻辑。

事件就是观察者模式的一种应用。

监听系统的某一个行为,实时获取并执行自己负责的代码。

以上是詳解PHP設計模式之觀察者模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn