觀察者模式
現(xiàn)在有一個氣象站,它是獲取濕度、溫度、氣壓數(shù)據(jù)的物理裝置,WeatherData追蹤氣象站的數(shù)據(jù)變化,并且更新到報告班板,如圖

weather1.png
需求:
- WeatherData 類有getter 方法,可以取得溫度、濕度、氣壓、三個測量值。當測量數(shù)據(jù)發(fā)送變化時,WeatherData measurementsChanged() 方法就會被調(diào)用(先不管它是如何被調(diào)用的,只要記住一點數(shù)據(jù)變化會調(diào)用此方法)
- 需要實現(xiàn)三個布告板,目前狀況布告、氣象統(tǒng)計布告、天氣預報布告;并且系統(tǒng)需可擴展,實現(xiàn)讓其他開發(fā)人員建立定制的布告板,用戶可以隨便添加或者刪除 任何布告板。

weather2.png
一般我們是這樣實現(xiàn)的
public class WeatherData {
// 實例變量聲明
pubic void measuremetnsChanged(){
float temp = getTemperature();
float humidity = getHumidity();
float pressure = getPressure();
currentConditionsDisplay.update(temp, humidity, pressure);
statisticsDisplay.update(temp, humidity, pressure);
forecastDisplay.update(temp, humidity, pressure);
}
// 這里WeatherData 其他方法
}
這樣實現(xiàn)由缺點
- 對于每個新的布告板,我們都得修改代碼,我們尚未封裝改變的部分
- 布告板沒有實現(xiàn)一個共同的 接口,至少update 看來參數(shù)沒有發(fā)生變化
- 我們無法在運行時動態(tài)地添加、刪除布告板
利用觀察者模式來設計,觀察者模式就類似在生活中我們 向雜志社訂閱或者取消訂閱報紙、雜志。結(jié)合模型對象的編程思想,雜志社需要提供 訂閱、取消訂閱、通知用戶的方法,而訂閱者肯定要提供一個 讓雜志社聯(lián)系上自己的方法。聯(lián)系上面的需求,畫出類圖

weather3.png
所以我們可以把實現(xiàn)上面需求的類圖設計為

weather4.png
實現(xiàn)代碼如下
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifybservers();
}
public interface Observer {
public void update(float temp, float humidity, float pressure);
}
public interface DisplayElement{
public void display();
}
// 實現(xiàn) weatherData
public class WeatherData implements Subject {
private ArrayList observers;
private float temperature;
private float humidity;
private float pressure;
public WeatherData(){
observers = new ArrayList();
}
public void registerObserver(Observer o){
observers.add(o);
}
public void removeObserver(Observer o){
int i = observers.indexof(o);
if(i >= 0){
observer.remove(i);
}
}
public void notifyObservers(){
for(int i=0; i< observers.size(); i++){
Observer observer = (Observer)observers.get(i);
Observer.update(temperature, humidity, pressure);
}
}
// 測量數(shù)據(jù)改變,該方法會被調(diào)用
public void measurementsChanged(){
notifyObservers();
}
}
// 創(chuàng)建布告板
public class CurrentconditionsDisplay implements Observer, DisplayElement {
private float temperature;
private float humidity;
private Subject weatherData;
public CurrentconditionsDisplay(Subject weatherdata){
this.weatherData = weatherData;
weatherData.registerobserver(this);
}
public void update (float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
display();
}
public void display(){
// ....
}
}
觀察者模式,定義了對象之間一對多依賴,當一個對象改變狀態(tài),它的所有依賴者都會接收到通知并自動更新