讓你的物件,知悉狀況
應用就是利用WeatherData
物件取得感測器資料,並更新三個佈告板:目前狀況、氣象統計和天氣預報。
WeatherData
類public class WeatherData {
// 範例變數宣告
public void measurementsChanged() {
// 取得測量值
float temp = getTemperature();
float humidty = getHumidity();
float pressure = getpRESSURE();
// 呼叫每個佈告板更新顯示,傳入最新的測量
currentConditionsDisplay.update(temp, humidity, pressure);
statisticsDisplay.update(temp, humidity, pressure);
forecasDisplay.update(temp, humidity, pressure);
}
// 其它方法
}
這樣做有什麼不對
違反設計原則,最好是把不變的部分和會改變的東西分別封裝起來。
// 呼叫每個佈告板更新顯示,傳入最新的測量
currentConditionsDisplay.update(temp, humidity, pressure);
statisticsDisplay.update(temp, humidity, pressure);
forecasDisplay.update(temp, humidity, pressure);
這部分可能會改變的東西,可以提出來單獨封裝。
針對介面程式設計,而不是針對實現程式設計,上面的update()引數都是溫度、溼度、氣壓,看起來像是一個統一的介面。這樣針對具體的實現程式設計,會導致我們以後在增加或刪除佈告板時必須修改程式。
觀察者模式定義了物件之間的一對多依賴,這樣一來,當一個物件改變狀態時,它的所有依賴者都會收到通知並自動更新。
關於觀察者的一切,主題只知道觀察者實現了某個介面(也就是Observer介面)。主題不需要知道觀察者具體類是誰,做了些什麼或其它任何細節。改變主題或觀察者其中一方,並不會影響另一方。因為兩者是鬆耦合的,只要他們之間的介面仍被遵守,我們就可以自由地改變他們。
設計原則:
為了互動物件之間的鬆耦合設計而努力。
鬆耦合的設計之所以能讓我們建立有彈性的OO
系統,能夠應對變化,是因為物件之間的互相依賴降到了最低。
除了自定義介面實現觀察者模式,還可以藉助Java已經封裝好的工具類來實現。
優點:使用上更加方便,甚至可以使用推(push)或拉(pull)的方式傳送資料。
tips:
這裡面使用了一個setChanged()
方法用來標記狀態已經改變的事實。有什麼用呢?
使得程式碼更加有彈性,比方說,如果沒有setChanged()
方法,氣象站的測量非常精確,每次溫度值有十分之一度就開始更新資料,現在我希望半度以上才更新資料,就可以在溫度到達半度時呼叫setChanged()
方法,進行有效的數值更新。
觀察者模式——在物件之間定義一對多的依賴,這樣一來,當一個物件改變狀態依賴它的物件就會收到通知,並自動更新。
程式碼地址: