<a href="http://www.cnblogs.com/wolf-sun/p/3468100.html">[Head First設計模式]山西面館中的設計模式——裝飾者模式</a>
不知不自覺又将設計模式融入生活了,吃個飯也不得安生,也發現生活中的很多場景,都可以用設計模式來模拟。原來設計模式就在我身邊。
為什麼觀察者模式會出現呢? 為了建立一種對象與對象之間的依賴關系,一個對象發生改變時将自動通知其他對象,其他對象将相應做出反應。在此,發生改變的對象稱為觀察目标,而被通知的對象稱為觀察者,一個觀察目标可以對應多個觀察者,而且這些觀察者之間沒有互相聯系,可以根據需要增加和删除觀察者,使得系統更易于擴充,這就是為什麼需要觀察者模式。
觀察者模式(Observer Pattern):定義了對象之間的一種一對多依賴關系,使得每當一個對象狀态發生改變時,其相關依賴對象皆得到通知并被自動更新。觀察者模式又被稱為釋出-訂閱(Publish/Subscribe)模式,模型-視圖(Model/View)模式,源-監聽器(Source/Listener)模式,或從屬者(Dependents)模式。觀察者模式是一種對象行為型的模式。

當兩個對象是松耦合的,它們之間能夠互動,但是互相了解的很少。
觀察者模式提供了主題和觀察者之間的松耦合設計。因為主題隻知道觀察者實作了某個接口(即Observer接口)。主題不需要知道具體觀察者是誰,做了些什麼或其它任何細節。要增加新的觀察者或删除觀察者,主題不會受到任何影響,不必修改主題代碼。
可以獨立地複用主題和觀察者,他們之間互不影響,即是松耦合。
設計原則:在互動的對象之間争取松耦合設計 由于松耦合設計使得對象間的依賴最小化,是以,我們能夠建立柔性的oo系統,應對變化的情況,因為對象間的依賴降到了最低。
書中的氣象站例子:
代碼實作:
在WeatherData中實作主題接口
建立布告闆
測試代碼
結果:
場景:山西面館中,我點餐,服務員傳話給廚師,廚師應答,廚師做飯。
分析:在這個場景中,我:被觀察者,服務員,廚師:觀察者。
我:“一份蕃茄雞蛋湯面”
一系列動作
服務員:1.向廚師傳話“一份蕃茄雞蛋湯面”
廚師:1.收到,2.開始做。
在.NET中,C#使用委托以及事件,可以很好的實作觀察者模式。委托相當于“訂閱清單”的角色,當目标中關聯了該委托的事件被觸發時,則委托将自動按序執行觀察者注冊于委托中的方法。
代碼實作:
基類的實作
觀察者實作
被觀察者
測試:
當一個對象的資料更新時需要通知其他對象,但這個對象又不希望和被通知的那些對象形成緊耦合。
當一個對象的資料更新時,這個對象需要讓其他對象也各自更新自己的資料,但這個對象不知道具體有多少對象需要更新資料
觀察者模式與備忘錄模式的關系
觀察者模式使用了備忘錄模式(Memento Pattern),暫時将觀察者對象存儲在被觀察者對象裡面
觀察者模式與MVC模式的關系
觀察者模式可以用來實作MVC模式。觀察者模式中的主題便是MVC模式中的模型加控制器,而觀察者便是視圖
一般情況下,MVC是觀察者模式、組合模式、政策模式等設計模式的組合。
觀察者模式的有點
1,具體主題和具體觀察者是松耦合關系。
由于主題(Subject)接口僅僅依賴于觀察者(Observer)接口,是以具體主題隻是知道它的觀察者是實作觀察者(Observer)接口的某個類的執行個體,但不需要知道具體是哪個類。同樣,由于觀察者僅僅依賴于主題(Subject)接口,是以具體觀察者隻是知道它依賴的主題是實作主題(subject)接口的某個類的執行個體,但不需要知道具體是哪個類。
2,觀察者模式滿足“開-閉原則”。
主題(Subject)接口僅僅依賴于觀察者(Observer)接口,這樣,我們就可以讓建立具體主題的類也僅僅是依賴于觀察者(Observer)接口,是以如果增加新的實作觀察者(Observer)接口的類,不必修改建立具體主題的類的代碼。同樣,建立具體觀察者的類僅僅依賴于主題(Observer)接口,如果增加新的實作主題(Subject)接口的類,也不必修改建立具體觀察者類的代碼。
觀察者模式的缺點
如果一個被觀察者對象有很多直接和間接的觀察者的話,将所有的觀察者都通知到會花費很多時間。
如果在被觀察者之間有循環依賴的話,給觀察者會觸發它們之間進行循環調用,導緻系統崩潰。在使用觀察者模式時要特别注意這一點。
雖然觀察者模式可以随時使觀察者知道所觀察的對象發生了變化,但是觀察者模式沒有相應的機制是觀察者知道所觀察的對象是怎麼發生變化的
參考書
Head First 設計模式