一、模式定義
定義一種對象之間的一對多的依賴關係,這樣一來,當一個主題對象改變狀態時,它的所有觀察者都會收通知並自動更新。
二、 所體現出的設計原則
為互動對象之間的鬆散耦合設計而努力。
三、UML圖示
四、應用情境
1. 當一個抽象模型有兩個方面, 其中一個方面依賴於另一方面。將這二者封裝在獨立的對象中以使它們可以各自獨立地改變和複用。
2, 當對一個對象的改變需要同時改變其它對象, 而不知道具體有多少對象有待改變。
3. 當一個對象必須通知其它對象,而它又不能假定其它對象是誰。換言之, 你不希望這些對象是緊密耦合的。
五、注意事項
Subject類需要維護一個列表,儲存已經向其註冊了的Observer對象列表(當然用C++實現的話,就是儲存Observer基類指標)。Subject必須實現一種“推資料”的方法,即在“通知”各個Observer更新資料時,將Subject自身維護的全部資料,通過UpdateData(para1, para2, …)介面的調用傳遞給各個Observer對象。另一方面,Subject也可以實現很多介面,供各個observer“拉資料”。
“推資料”優點是:介面簡單,不必要為每個資料提供一個get方法供Observer調用(想想看,如果有100個資料成員,就必須提供100個介面)。
“推資料”缺點是:強迫Observer接收全部資料,即便某些observer只需要部分資料;同時暴露了Subject的資料。
“拉資料”優點是:比較靈活,如果本身資料增加或者減少,只需要提供新的介面,或者刪除舊的介面就可以了。
“拉資料”缺點是:如果一個observer對象需要的狀態很多,就必須多次調用Subject提供的介面來獲得,比較麻煩。
六、舉例說明
以天氣預報為例。氣象局的資料擷取中心會定時從檢測儀器上採集資料,經過大量超級複雜的計算並後產生新的天氣預報,這裡資料擷取中心就好比是一個subject。然後各大門戶網站的天氣預報欄目就好比是各個觀察者對象,一旦資料中心有通知,則各個觀察者都可以取得最新的天氣情況資訊。當然啦,這個例子裡的觀察者模式是一個更大的,分布式的執行個體,可以利用各種分布式技術如CORBA,EJB等實現。
七、程式碼範例
維基百科:http://zh.wikipedia.org/wiki/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F