觀察者模式:
觀察者模式(Observer Pattern):定義對象間的一種一對多依賴關係,使得每當一個對象狀態發生改變時,其相關依賴對象皆獲得通知並被自動更新。觀察者模式又叫作發佈-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式、源-監聽器(Source/Listener)模式或從屬者(Dependents)模式。
觀察者模式是一種對象行爲型模式。php
模式動機
創建一種對象與對象之間的依賴關係,一個對象發生改變時將自動通知其餘對象,其餘對象將相應作出反應。在此,發生改變的對象稱爲觀察目標,而被通知的對象稱爲觀察者,一個觀察目標能夠對應多個觀察者,並且這些觀察者之間沒有相互聯繫,能夠根據須要增長和刪除觀察者,使得系統更易於擴展,這就是觀察者模式的模式動機。html
觀察者模式包含以下角色:
Subject: 目標
ConcreteSubject: 具體目標
Observer: 觀察者
ConcreteObserver: 具體觀察者函數
UML類圖:測試
適用性:
當一個抽象模型有兩個方面, 其中一個方面依賴於另外一方面。將這兩者封裝在獨立的對象中以使它們能夠各自獨立地改變和複用。
當對一個對象的改變須要同時改變其它對象, 而不知道具體有多少對象有待改變。
當一個對象必須通知其它對象,而它又不能假定其它對象是誰。換言之, 你不但願這些對象是緊密耦合的this
//代碼實現spa
<?php header("Content-type:text/html;Charset=utf-8"); //目標接口,定義觀察目標要實現的方法 abstract class Subject{ abstract function attach(Observer $observer); //添加觀察者 abstract function detach(Observer $observer); //去除觀察者 abstract function notify(); //知足條件時通知全部觀察者修改 abstract function condition($num); //發起通知的條件 } //具體觀察目標 class ConcreteSubject extends Subject{ private $observers = array(); //添加觀察者 function attach(Observer $observer){ $this->observers[] = $observer; } //移除觀察者 function detach(Observer $observer){ $key=array_search($observer, $this->observers); if($key !== false){ //注意不要寫成!=,表達式0!=flase爲flase unset($this->observers[$key]); } } //通知全部全部觀察者修改 function notify(){ foreach($this->observers as $observer){ $observer->update(); } } //發起通知的條件 function condition($num){ if($num>100){ $this->notify(); } } } //抽象觀察者接口,定義全部觀察者共同具備的屬性——執行修改 abstract class Observer{ abstract function update(); } //具體觀察者類,實現抽象觀察者接口 class ConcreteObserverA extends Observer{ function update(){ echo "A報告:敵軍超過一百人了,快撤!<br>"; } //其餘函數 function eat(){ echo "A在吃飯"; } } class ConcreteObserverB extends Observer{ function update(){ echo "B報告:敵軍超過一百人了,快撤!<br>"; } //其餘函數 function sleep(){ echo "B在睡覺"; } } //測試 $observerA = new ConcreteObserverA(); $observerB = new ConcreteObserverB(); $concreteSubject = new ConcreteSubject(); $concreteSubject->attach($observerA); //添加觀察者A $concreteSubject->detach($observerA); //去除觀察者A $concreteSubject->attach($observerA); $concreteSubject->attach($observerB); $concreteSubject->condition(1000); ?>