摘要:Yii2的事件採用了“觀察者模式”,先了解觀察者,再學事件就容易了。
首先不要被名字所嚇倒,往下看,它真的很簡單。
先來一個比較高大上的定義:觀察者模式定義了一系列物件之間的一對多關係,當一個物件改變狀態後,其他依賴者都會收到通知。
看明白了麼?
如果沒明白我們再來一個生活一點的:觀察者模式就是訂報紙的模式,你和一些人向某個報社訂報紙,只要有新報紙出版,報社就會給你們送來,具體你們怎麼看和報社無關,只要報社不倒閉,就會一直送你們。
當然,你也可以取消訂閱。
觀察者模式== 報社+ 訂報紙的人
#無論你明白了哪種定義,記住一點,「觀察者模式」最屌的地方就是讓一些彼此依賴的類松耦合,牛逼的系統是什麼樣的?那就是每個物件間的依賴程度降到冰點,但依然可以互動。
我想到此刻,你已經清楚了觀察者模式,但是作為一個語言類文章,不寫點程式碼總說不過去,我們接下來用程式碼來實現上面的需求。
我們先來一個不用觀察者模式的程式碼
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中文網其他相關文章!