2 Observer Pattern(觀察者模式)
2.1設(shè)計原則一
為了交互對象的松耦合設(shè)計而努力
下面舉個例子說明這個原則。
1)案例分析一:
REQ1:Vander接到一個外包的項(xiàng)目,項(xiàng)目是關(guān)于下一代Internet的氣象觀測站,此系統(tǒng)中三個部分是氣象站(獲取實(shí)際氣象數(shù)據(jù)的物理裝置),WeatherData對象(追蹤來自氣象站的數(shù)據(jù),并更新布告板)和布告板(顯示目前天氣狀況給用戶看)。

Vander的工作就是建立一個應(yīng)用,利用WeatherData對象取得數(shù)據(jù),并更新是三個布告板:目前狀況、氣象統(tǒng)計、天氣預(yù)報。
委托方發(fā)送過來的WeatherData類:

所以Vander的工作就是完成measurementsChanged這個方法,好讓它更新目前狀況、氣象統(tǒng)計和天氣預(yù)報的顯示布告板。
解決方法1:Vander 就開始設(shè)計了

public void measurementsChanged() {
currentConditionDisplayer.update(temperature, humidity, pressure);
forecastDisplayer.update(temperature, humidity, pressure);
statisticDisplayer.update(temperature, humidity, pressure);
}
這個方法出現(xiàn)了以下4個問題:
1、針對實(shí)現(xiàn)編程而不是針對接口編程:首先更新數(shù)據(jù)的這個操作都是這三個布告板自己完成的,而不是由第三者來幫助完成(回想鴨子飛行的實(shí)現(xiàn)方法,鴨子飛行是由專門的飛行類來完成的,而不是由鴨子本身來實(shí)現(xiàn)的,鴨子本身只是調(diào)用了飛行類)。
2、對于每個新的布告板,都需要修改WeatherData這個類。
3、無法動態(tài)添加或者刪除布告板:即每次增加刪除布告板都需要重新運(yùn)行程序
4、沒對變化的部分進(jìn)行封裝:WeatherData會因?yàn)椴几姘宓脑黾訙p少而改變,要針對這樣的改變進(jìn)行一定的封裝
解決方法2 觀察者模式:

Vander聽說了觀察者模式之后使用觀察者模式進(jìn)行設(shè)計,先說明一下觀察者模式,實(shí)際上就是發(fā)布-訂閱模式,簡單舉個例子,Vander和Pander和Triangle三個人一起訂了雜志,每天雜志社都會給他們推送雜志,有一天Triangle不想訂雜志了,跟雜志社取消訂閱,然后Triangle就不會收的雜志了,而Vander跟Panda繼續(xù)收到雜志,Triangle發(fā)現(xiàn)沒有雜志的日子太無聊了,所以又去訂閱雜志,于是他又能收到雜志了。實(shí)際上發(fā)布-訂閱模式,就是一種推數(shù)據(jù)的方式,由主題者(發(fā)布者)將數(shù)據(jù)推給觀察者(訂閱者)。
上圖中的做法實(shí)際上就是讓主題者在更新消息的同時然后幫觀察者調(diào)用觀察者的update方法。
解決方法3(使用Java api的觀察者):

注意Java Api的方式有一定的局限性,首先Observable是作為父類的,所以子類的WeatherData要成為主題者只能繼承Observable,Observable實(shí)現(xiàn)的notifyObservers方法中需要先調(diào)用setChanged方法,這樣子是為了保證不是每次更新數(shù)據(jù)都去通知布告板,但是Observable的setChanged方法是用protected保護(hù)起來了,這就意味著需要子類繼承Observable才能調(diào)用setChanged方法,這也就違反了第三條原則“多用組合,少用繼承”。
面向?qū)ο蠡A(chǔ)
抽象、封裝、多態(tài)、繼承
四大原則
設(shè)計原則一:封裝變化
設(shè)計原則二:針對接口編程,不針對實(shí)現(xiàn)編程。
設(shè)計原則三:多用組合,少用繼承。
設(shè)計原則四:為交互對象之間的松耦合設(shè)計而努力
模式
觀察者模式:在對象之間定義一對多的依賴,這樣一來,當(dāng)一個對象改變狀態(tài),依賴它的對象都會受到通知并自動更新。