C#面向對象設計模式縱橫談 第19講:Observer 觀察者模式

人文精神  >>>  技術的天空 溫和的思緒

2006.7.19 李建忠

發布-訂閱模型

image

當我們賬戶的金額有任何的操作,如果我們訂閱了服務,例如手機、Email等,那么我們都會得到通知。

 

動機(Motivation)

在軟件構建過程中,我們需要為某些對象建立一種“通知依賴關系”——一個對象(目標對象)的狀態發生改變,所有的依賴對象(觀察者對象)都將得到通知。如果這樣的依賴關系過于緊密,將使軟件不能很好地抵御變化。

使用面向對象技術,可以將這種依賴關系弱化,并形成一種穩定的依賴關系。從而實現軟件體系結構的松耦合。

 

意圖(Intent)

定義對象間的一種一對多的依賴關系,以便當一個對象的狀態發生改變時,所有依賴于它的對象都得到通知并自動更新

——《設計模式》GoF

 

例說Observer應用

image

image

這樣設計,如果還有其他設備需要通知,那么我們每次都需要頻繁地修改BankAccount。

 

改進的設計

image

image

image

image

image

 

結構(Structure)

image

ConcreteSubject對應例子中的BankAccount,ConcreteObserver對應Emailer、Mobile等。

 

Observer模式的幾個要點

使用面向對象的抽象,Observer模式使得我們可以獨立地改變目標與觀察者(面向對象中的改變不是指改代碼,而是指擴展、子類化、實現接口),從而使二者之間的依賴關系達致松耦合。

目標發送通知時,無需指定觀察者,通知(可以攜帶通知信息作為參數)會自動傳播。觀察者自己決定是否需要訂閱通知,目標對象對此一無所知。

在C#的event中,委托充當了抽象的Observer接口,而提供事件的對象充當了目標對象。委托是比抽象Observer接口更為松耦合的設計。

 

.NET框架中的Observer

image

image

AccountChange委托里面會遍歷所有的委托鏈表里面的對象然后調用。

image

Emailer這里雖然并沒有實現接口,但它其實隱含的約定了接口,它的方法名字可以不一定是Update,使得松耦合更加靈活。

image

委托的+號其實就是往委托鏈表里面Add通知的方法,委托事件把遍歷的方法和添加刪除方法都替我們做好了,但實現的原理還是和我們第一個例子一樣。

Emailer和BankAccount之間沒有強依賴,它們之間的依賴是靠第三方的委托依賴的,只要委托穩定,其它都會穩定。所以我們完全可以把委托看成一個接口,我們盡量要只依賴于委托,而不要讓委托來依賴我們具體的類型。

2010.10.19


MSDN 網絡廣播 李建忠 2013-08-22 08:51:41

[新一篇] C#面向對象設計模式縱橫談 第20講:Chain Of Responsibility 職責鏈模式

[舊一篇] C#面向對象設計模式縱橫談 第18講:Iterator 迭代器模式
回頂部
寫評論


評論集


暫無評論。

稱謂:

内容:

驗證:


返回列表