【HeadFirst 設計模式】觀察者模式

觀察者模式:定義了對象之間的一對多依賴,這樣一來,當一個對象改變狀態時,它的所有依賴者都會收到通知並自動更新。


觀察者模式的類圖:


設計原則:爲了交互對象之間的鬆耦合設計而努力。

觀察者模式提供了一種對象設計,讓主題和觀察者之間鬆耦合。主題只知道觀察者實現了某個接口(Observer接口)。主題不需要知道觀察者的具體類是誰、做了些什麼或其它任何細節。

鬆耦合的設計之所以能讓我們建立有彈性的OO系統,能夠應付變化,是因爲對象之間的互相依賴降到了最低。

當兩個對象之間鬆耦合,它們依然可以交互,但是不清楚彼此的細節。


Java內置的觀察者模式

java.util包內包含最基本的Observer接口和Observable類。

類圖:


示例:建立一個應用,利用WeatherData對象取得數據(temperature, humidity, pressure),並更新三個佈告板:StatisticsDisplay, ForecastDisplay, ThirdPartyDisplay。

WeatherData.java

import java.util.Observable;
import java.util.Observer;
	
public class WeatherData extends Observable {
	private float temperature;
	private float humidity;
	private float pressure;
	
	public WeatherData() { }
	
	public void measurementsChanged() {
		setChanged(); //在調用notifyObservers之前,要先調用setChanged()來指示狀態已經改變
		notifyObservers();
	}
	
	public void setMeasurements(float temperature, float humidity, float pressure) {
		this.temperature = temperature;
		this.humidity = humidity;
		this.pressure = pressure;
		measurementsChanged();
	}
	
	public float getTemperature() {
		return temperature;
	}
	
	public float getHumidity() {
		return humidity;
	}
	
	public float getPressure() {
		return pressure;
	}
}


CurrentConditionsDisplay.java
import java.util.Observable;
import java.util.Observer;
	
public class CurrentConditionsDisplay implements Observer, DisplayElement {
	Observable observable;
	private float temperature;
	private float humidity;
	
	public CurrentConditionsDisplay(Observable observable) {
		this.observable = observable;
		observable.addObserver(this);
	}
	
	//增加Observable和數據對象作爲參數
	public void update(Observable obs, Object arg) {
		//確定可觀察者屬於WeatherData類型
		if (obs instanceof WeatherData) {
			WeatherData weatherData = (WeatherData)obs;
			this.temperature = weatherData.getTemperature();
			this.humidity = weatherData.getHumidity();
			display();
		}
	}
	
	public void display() {
		System.out.println("Current conditions: " + temperature 
			+ "F degrees and " + humidity + "% humidity");
	}
}

DisplayElement.java

public interface DisplayElement {
	public void display();
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章