PHP設計模式之 觀察者模式

2021-10-07 13:30:39 字數 3721 閱讀 8758

今天來介紹乙個很有用的設計模式,「觀察者模式」,顧名思義,既然有「觀察者」, 那麼一定就有「被觀察者」,從這個層面可以理解到,在這個設計模式中有兩個物件, 乙個是主體物件,乙個是客體物件,在實際的**實現上實際是「被觀察者」主動通知了「觀察者」。「被觀察者」是主體物件,現在看不懂沒關係,把下面的**抄幾遍就懂了。

php 提供了兩個內建介面來幫助實現「觀察者模式」, 其中「被觀察者」需要實現splsubject介面,「觀察者」需要實現sploberver

來看乙個例子:

<?php

class plugina implements splobserver

}class pluginb implements splobserver

}class user implements splsubject

public function attach(\splobserver $observer)

public function detach(\splobserver $observer)

}public function notify()

}}//-- 例項化主體物件

$user = new user();

//-- end

//-- 註冊外掛程式

$plugins = [

new plugina(),

new pluginb(),

];foreach ($plugins as $plugin)

//-- end

//-- 執行主體的業務**

$user->register('shanhuhai', '123456');

將以上**儲存即可執行。

以上**模擬了乙個呼叫註冊方法register時,通知相關外掛程式執行相應任務的機制。它使用觀察者模式實現了外掛程式的機制。

外掛程式物件pluginapluginb的例項就是「觀察者」,user類的例項$user是「被觀察者」,「觀察者」需要通過attach方法註冊到「被關觀察者」 上,

register方法被時,user會通過notify方法來通知所有的外掛程式,並將主體物件即被觀察者傳遞給外掛程式。

這裡僅僅是通過最簡單的**展示了什麼是觀察者模式,如果想實現外掛程式,我們應該能傳遞更多的資訊給外掛程式,比如我們想在外掛程式中針對主體物件的發生不同事件(不同的方法被呼叫)做不同的處理,我們可能需要「事件」的概念,你知道如何實現麼?

在實際的業務中,觀察者應該對不同的情況做出不同的發應,這個其實很簡單,我們加乙個給主體物件加乙個event的屬性就ok了。

<?php

/** * 支援了事件的版本

*/class plugina implements splobserver

}}class pluginb implements splobserver

if($subject->event == 'login')

}}class user implements splsubject

public function login($name, $password)

public function attach(\splobserver $observer)

public function detach(\splobserver $observer)

}public function notify()

}}//-- 例項化主體物件

$user = new user();

//-- end

//-- 註冊外掛程式

$plugins = [

new plugina(),

new pluginb(),

];foreach ($plugins as $plugin)

//-- end

//-- 執行主體的業務**

$user->register('shanhuhai', '123456');

$user->login('shanhuhai', '123456');

完成了這個之後你會發現乙個問題,目前來看我必須將所有的外掛程式例項化後才能註冊到主體物件中,那麼問題來了,如果乙個外掛程式,只處理部分事件,那麼如果在整個程式處理過程中這個事件沒有被觸發,那麼這個外掛程式的例項化是不是浪費了?

外掛程式可以根據不同的事件來做不同的業務處理,基本上很簡單,我們直接通過主體物件攜帶事件名稱即可。

下面我們要實現的是,只有在知道具體事件後才去例項化繫結了此事件的外掛程式。

下面是具體的實現:

<?php

/** * author: shanhuhai

* date: 2017/8/28 21:26

* mail: [email protected]

*/class plugina implements splobserver

}}class pluginb implements splobserver

if($subject->event == 'login')

}}class observer implements splobserver }}

public function update(\splsubject $subject) }}

}class user implements splsubject

public function login($name, $password)

public function attach(\splobserver $observer)

public function detach(\splobserver $observer)

public function notify()

}//-- 例項化主體物件

$user = new user();

//-- end

//-- 配置外掛程式

$config = [

'plugina' => ['register' ],

'pluginb' => ['register', 'login'],

];//-- end

//-- 註冊外掛程式

$observer = new observer($config);

$user->attach($observer);

//-- end

//-- 執行主體的業務**

$user->register('shanhuhai', '123456');

$user->login('shanhuhai', '123456');

其實觀察者模式還叫「發布/訂閱模式」, 這跟訊息佇列中說的「發布/訂閱」基本上是乙個意思,我們在$config的配置說明了訂閱關係,哪個外掛程式訂閱哪個事件,當被訂閱的事件發生時這個外掛程式就會收到訊息。比如plugina訂閱了register事件,當主體物件中 指定的event等於register時,plugina將會被例項化並接收到主體物件傳過來的資料。

在實際應用情況中,外掛程式應該在乙個特定目錄中,每個外掛程式是乙個檔案,以上機制想要應用到你的專案中,還要根據實際情況做相應修改。

php設計模式之 觀察者模式

觀察者模式 observer 當乙個物件狀態發生改變時,依賴它的物件全部收到通知,並自動更新。抽象被觀察者 abstract class eventgenerator 通知所有觀察者 public function notify 具體被觀察者class event extends eventgene...

PHP 設計模式之觀察者模式

介紹現在有兩派,有的人建議使用設計模式,有的人不建議使用設計模式!這就向寫文章一樣,有的人喜歡文章按照套路走,比如敘事性質的文章,時間,地點,人物,事件。而有的人喜歡寫雜文或者散文,有的人喜歡寫詩詞!很多時候,我看設計模式的時候,有些設計模式只是吻合我的 習慣。但是你硬去套它,那麼反而適得其反。很多...

php 設計模式之觀察者模式

觀察者模式 1.抽象事件發生類 abstract class eventgenerator 對 所有 觀察者 進行 事件 通知 function notify 2.宣告具體事件類 class event extends eventgenerator 3.宣告 乙個 觀察者 介面 inte ce ob...