觀察者模式:定義了對象之間的一對多依賴,這樣一來,當一個對象改變狀態時,它的所有依賴者都會收到通知並自動更新。
觀察者模式的類圖:
設計原則:爲了交互對象之間的鬆耦合設計而努力。
觀察者模式提供了一種對象設計,讓主題和觀察者之間鬆耦合。主題只知道觀察者實現了某個接口(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;
}
}
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();
}