你在編程中可能會遇到過,有時一個對象的狀態改變會影響很多類的行為,比較典型的就是在購買流程中,購買成功后會影響庫存、銷量、會通知發貨、有的還需要發送短信。購買這個行為在發生變化時需要同時發生其他行為,但是如果寫在一起,一旦流程發生變化,改起來會比較麻煩,將這些行為寫在一起的耦合度也太高,觀察者模式可以解決這個問題,通過觀察者和狀態主題互相注冊的方式,使主體在發生變化時能夠通知觀察者,兩者組合在一起,耦合度較低。實現一種自動更新機制。 上面這個例子好像還不能體現出觀察者模式的優勢,比如一個購物網站,各類商品的價格都是由匯率決定,當匯率發生改變,需要通知所有產品類目價格改變,但是產品類目的數目、有哪些都是不確定的,這讓它沒有辦法通知,也不能讓各個產品類目來主動查詢,所以此時必須使用觀察者模式來實現這個數據綁定,這讓我想起了C#中的數據綁定機制。
觀察者模式是通過一個叫Observer的接口實現,如果某個類需要作為觀察者,則需要實現這個類:
interface Observer{ function notefy($obj);}如果一個對象想要被觀察,需要一個注冊方法,這樣,觀察者對象可以用來注冊自己,
購物網站的貨品價格需要根據當天匯率來進行計算。這些產品項目需要作為“觀察者”觀察匯率這個主體。
<?php/*** */class ExchangeRate { static PRivate $instance = NULL; private $observers = array(); private $exchange_rate; private function ExchangeRate(); static private function getInstance(){ if(self::$instance == NULL) self::$instance = new ExchangeRate(); return slef::$instance; } public function getExangeRate(){ return $this->$exchange_rate; } public function setExchangeRate($new_rate){ $this->exange_rate = $new_rate; $this->notifyObservers(); // 通知更新 } public function registObserver($obj){ $this->observers[] = $obj; } public notifyObservers(){ foreach ($this->observers as $obj) { $obj->notify($this); } } interface Observer{ function notify($obj); }/*** */class ProductIten implements Observer{ function __construct() { ExchangeRate::getInstance()->registObserver($this); } public function notify($obj){ if($obj instanceof ExchangeRate){ // 更新 print"數據已更新"; } }}$priduct1 = new ProductIten();ExchangeRate::getInstance()->setExchangeRate(2);?>新聞熱點
疑難解答
圖片精選