1. 程式人生 > >設計模式——02 觀察者模式

設計模式——02 觀察者模式

1 Observer Pattern(觀察者模式)

1.1設計原則一

         為了互動物件的鬆耦合設計而努力

         下面舉個例子說明這個原則。

1)案例分析一:

         REQ1Vander接到一個外包的專案,專案是關於下一代Internet的氣象觀測站,此係統中三個部分是氣象站(獲取實際氣象資料的物理裝置),WeatherData物件(追蹤來自氣象站的資料,並更新佈告板)和佈告板(顯示目前天氣狀況給使用者看)。

 

Vander的工作就是建立一個應用,利用WeatherData物件取得資料,並更新是三個佈告板:目前狀況、氣象統計、天氣預報。

委託方傳送過來的WeatherData類:

所以Vander的工作就是完成measurementsChanged這個方法,好讓它更新目前狀況、氣象統計和天氣預報的顯示佈告板。

解決方法1:Vander 就開始設計了

   public void measurementsChanged() {

      currentConditionDisplayer.update(temperature, humidity, pressure);

      forecastDisplayer.update(temperature, humidity, pressure);

      statisticDisplayer.update(temperature, humidity, pressure);

   }

存在的問題:

         這個方法出現了以下4個問題:

         1、針對實現程式設計而不是針對介面程式設計:首先更新資料的這個操作都是這三個佈告板自己完成的,而不是由第三者來幫助完成(回想鴨子飛行的實現方法,鴨子飛行是由專門的飛行類來完成的,而不是由鴨子本身來實現的,鴨子本身只是呼叫了飛行類)。

         2、對於每個新的佈告板,都需要修改WeatherData這個類。

         3、無法動態新增或者刪除佈告板:即每次增加刪除佈告板都需要重新執行程式

         4、沒對變化的部分進行封裝:WeatherData會因為佈告板的增加減少而改變,要針對這樣的改變進行一定的封裝

        

解決方法2 觀察者模式:

    Vander聽說了觀察者模式之後使用觀察者模式進行設計,先說明一下觀察者模式,實際上就是釋出-訂閱模式,簡單舉個例子,Vander和Pander和Triangle三個人一起訂了雜誌,每天雜誌社都會給他們推送雜誌,有一天Triangle不想訂雜誌了,跟雜誌社取消訂閱,然後Triangle就不會收的雜誌了,而Vander跟Panda繼續收到雜誌,Triangle發現沒有雜誌的日子太無聊了,所以又去訂閱雜誌,於是他又能收到雜誌了。實際上釋出-訂閱模式,就是一種推資料的方式,由主題者(釋出者)將資料推給觀察者(訂閱者)。

上圖中的做法實際上就是讓主題者在更新訊息的同時然後幫觀察者呼叫觀察者的update方法。

         解決方法3(使用Java api的觀察者):

         注意Java Api的方式有一定的侷限性,首先Observable是作為父類的,所以子類的WeatherData要成為主題者只能繼承Observable,Observable實現的notifyObservers方法中需要先呼叫setChanged方法,這樣子是為了保證不是每次更新資料都去通知佈告板,但是Observable的setChanged方法是用protected保護起來了,這就意味著需要子類繼承Observable才能呼叫setChanged方法,這也就違反了第三條原則“多用組合,少用繼承”。

面向物件基礎

         抽象、封裝、多型、繼承

四大原則

設計原則一:封裝變化

設計原則二:針對介面程式設計,不針對實現程式設計。

         設計原則三:多用組合,少用繼承。

         設計原則四:為互動物件之間的鬆耦合設計而努力

 

模式

觀察者模式:在物件之間定義一對多的依賴,這樣一來,當一個物件改變狀態,依賴它的物件都會受到通知並自動更新。

 

最後獻上此次設計的原始碼,有需要的小夥伴可以下載來執行一下,首先先自己進行設計,然後再參考,這樣才能加深觀察者模式的理解。