解析PHP觀察者模式Observer
一個'演員'(被觀察者),一群'觀眾'(觀察者),一臺'攝影機'(記錄容器)
【觀察者模式中主要角色】
1.抽象主題(Subject)角色:主題角色將所有對觀察者對象的引用保存在一個集合中,每個主題可以有任意多個觀察者。 抽象主題提供了增加和刪除觀察者對象的接口。
2.抽象觀察者(Observer)角色:為所有的具體觀察者定義一個接口,在觀察的主題發生改變時更新自己。
3.具體主題(ConcreteSubject)角色:存儲相關狀態到具體觀察者對象,當具體主題的內部狀態改變時,給所有登記過的觀察者發出通知。具體主題角色通常用一個具體子類實現。
4.具體觀察者(ConcretedObserver)角色:存儲一個具體主題對象,存儲相關狀態,實現抽象觀察者角色所要求的更新接口,以使得其自身狀態和主題的狀態保持一致。
【使用場景】
假設項目經理讓我們寫了一個登陸接口,咔咔擦擦寫完了
第二天讓我們加入統計登陸次數,然后在后面加代碼第三天讓我們判斷登陸地區,又在后面加代碼第四天讓我們在用戶登陸后推送活動,再再后面加代碼第N天,這個接口已經雜亂到沒人想維護了
我們需要讓項目保持高內聚低耦合,就可以用到觀察者模式(非必須,看需求)
【觀察者模式與其它模式】
1.【中介者模式】(Mediator):通過封裝復雜的更新語義,ChangeManager充當目標和觀察者之間的中介者。2.【單例模式】(singleton模式):ChangeManager可使用Singleton模式來保證它是唯一的并且是可全局訪問的。
代碼示例接口示例
// 主題接口interface Subject{ public function register(Observer $observer); public function notify();}// 觀察者接口interface Observer{ public function watch();}
Subject就是被觀察者,Observer就是觀眾,也就是觀察者
被觀察者
// 被觀察者class Action implements Subject{ public $_observers=array(); public function register(Observer $observer){ $this->_observers[]=$observer; } public function notify(){ foreach ($this->_observers as $observer) { $observer->watch(); } } }
Action實現了被觀察者接口,他現在就是被觀察者,再定義一個$_observers數組,他就是記錄觀眾的容器了。
首先實現register方法,用它傳入一個觀察者,然后塞到數組里,再實現notify()方法,它會遍歷容器數組,執行每個觀察者的watch()方法。
觀察者
// 觀察者class Cat implements Observer{ public function watch(){ echo 'Cat watches TV<hr/>'; } } class Dog implements Observer{ public function watch(){ echo 'Dog watches TV<hr/>'; } } class People implements Observer{ public function watch(){ echo 'People watches TV<hr/>'; } }
這里定義了三個觀察者,全都實現了Observer接口,前面的Subject會循環調用每個觀察者的watch()方法,所以我們需要實現每個觀察者的watch()方法。
調用
// 應用實例$action=new Action();$action->register(new Cat());$action->register(new People());$action->register(new Dog());$action->notify();
首先new被觀察者對象,執行它的register()方法,把每個觀察者都放入容器數組,最后執行notify()方法,通知所有觀察者執行自己的方法。
PHP原生自帶的觀察者模式
PHP有自帶的觀察者模式
splsubject接口 - 被觀察者 Observer接口 - 觀察者 SplObjectStorage對象 - 容器首先我們有一個用戶登錄類
class user{ public function login() { echo ’登錄完畢’ }
讓他實現splsubject接口成為被觀察者。
首先在構造函數里,讓他new SplObjectStorag()對象并賦值到屬性上方便后面調用 實現attach()方法,用來注冊觀察者 實現detach()方法,用來刪除觀察者 實現notify()方法,用來遍歷容器,調用每個觀察者的update方法(必須是update) rewind方法是容器指針重置到最開始,valid方法檢測容器是否遍歷完成并返回布爾,current方法是獲取當前的觀察者,next方法是將指針后移一位 修改login()方法,在里面調用notify()來通知觀察者事件完成了class user implements splsubject{ protected $observer = null; public function __construct() {$this->observer = new SplObjectStorage(); } public function login() {$this->notify();echo ’登錄完畢’; } public function attach(SplObserver $observer) {$this->observer->attach($observer); } public function detach(SplObserver $observer) {$this->observer->detach($observer); } public function notify() {$this->observer->rewind();while ($this->observer->valid()){ $observer = $this->observer->current(); $observer->update($this); $this->observer->next();} }}
觀察者
每個觀察者實現SplObserver接口,并實現update()方法
class cat implements SplObserver { public function update(SplSubject $subject) {echo ’小貓叫一下’; }}class dog implements SplObserver { public function update(SplSubject $subject) {echo ’小狗吼一聲’; }}
應用
// 實時觀察$user = new user();$user->attach(new cat());$user->attach(new dog());$user->login();
以上就是解析PHP觀察者模式(Observer)的詳細內容,更多關于PHP觀察者模式(Observer)的資料請關注好吧啦網其它相關文章!
相關文章: