觀察者模式的使用具有廣泛性今野。是一種java設計模式。觀察者模式的定義是定義對象間一種一對多的依賴關系罐农,是的沒當一個對象改變狀態(tài)条霜,則所有依賴于它的對象都會得到通知并自動更新。
二.觀察者模式的使用場景
(1).關聯(lián)行為場景涵亏,需要注意的是宰睡,關聯(lián)行為是可拆分的,而不是“組合”關系
(2).事件多級觸發(fā)場景
(3).跨系統(tǒng)的消息交換場景气筋,如消息隊列拆内,事件總線的處理機制。
三.觀察者模式的UML類圖
角色介紹:
subject:抽象主題(Observer)宠默,也就是被觀察observable的角色麸恍,抽象主題角色把所有觀察者對象的引用保存在一個集合里,每個主題都可以有任意數(shù)量的觀察者搀矫,抽象主題提供一個接口抹沪,可以增加或刪除觀察者對象。
concreteSubject:具體主題(ConcreteObservable)瓤球,該角色將有關狀態(tài)存入具體觀察對象,在具體主題的內(nèi)部狀態(tài)發(fā)生改變時冰垄,給所有注冊過的觀察者發(fā)出通知蹬癌,具體主題角色又叫具體被觀察這(ConcreteObservable)角色
observale:抽象觀察者,該角色是觀察者的抽象類虹茶,它定義了更新接口虏肾,使得在得到主題的更改通知時更新自己吹埠。
ConcreteObserver:具體的觀察者第步,該角色實現(xiàn)抽象觀察者角色所定義的更新接口,以便在主題的狀態(tài)發(fā)生變化時更新自身的狀態(tài)缘琅。
異常信息的捕獲對編程測試有著重要的意義粘都,這里結合觀察者模式,探索如何處理異常信息刷袍。
筆者覺得翩隧,所謂觀察者模式,必須有兩個重要組成部分:一個主題對象呻纹,多個觀察者堆生。在使用的時候,我們可以將觀察者像插頭一樣插到主題對象這個插座上雷酪,利用主題對象完成相應功能顽频。既然觀察者要作為插頭,必須要有一個統(tǒng)一的口徑才能插到相同的插座上太闺,因而先定義一個接口糯景,Exception_Observer.php:
<?php?
/**
?* 定義的規(guī)范?
?*/
interface Exception_Observer{
? ? public function update(Observer_Exception $e);
}
??>
我們可以清楚地看到,靜態(tài)變量$_observers用來放置插入的觀察者省骂,notify()用來通知所有觀察者對象蟀淮。這里需要注意 $observer->update($this); 里面 $this 的用法,很多初學者會感到“原來 $this 也可以這么用啊”钞澳。一個小問題: $_observers 不是靜態(tài)變量可不可以怠惶? 這個問題我們后面回答。
定義兩個觀察者轧粟,原則上實現(xiàn)接口所定義的功能策治。
設計完所有該有的主體對象和插件,我們做個小小的測試:
<?php?
require 'Exception_Observer.php';
require 'Observer_Exception.php';
require 'Logging_Exception_Observer.php';
require 'Emailing_Exception_Observer.php';
Observer_Exception::attach(new Logging_Exception_Observer());
class MyException extends Observer_Exception{
? ? public function test(){
? ? ? ? echo 'this is ?a test';
? ? }
? ? public function test1(){
? ? ? ? echo "我是自定義的方法處理這個異常";
? ? }
}
try {
? ? throw new MyException("出現(xiàn)異常兰吟,記錄一下"); ? ?
} catch (MyException $e) {
? ? echo $e->getMessage();
? ? echo "<ht/>"; ? ?
}
?>
本實例首先先加載觀察者通惫,其后進行其他操作』彀回到上面提出的問題履腋, $_observers 可以不是靜態(tài)變量嗎?答案是不可以。如果 $_observers 不是靜態(tài)變量遵湖,加載觀察者的行為對后續(xù)操作沒有影響悔政。static讓所有實例成員共享某個變量。即便類繼承也同樣有效延旧。有興趣的可以繼續(xù)探索下static的神奇作用吧谋国。
本例顯示輸出與一般情況無異,但不同的是已在自定義的文件下生成了相應的日志迁沫。雖然最后實現(xiàn)的功能再簡單不過烹卒,很多人甚至可以用更少的代碼更簡單的方法實現(xiàn),但是弯洗,在實現(xiàn)更加復雜系統(tǒng)的情況下,觀察者模式給我們帶來很大方便逢勾。