定义:
在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。
大白话:
其实就是发布订阅模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。
类图:
例子:
恭喜贵公司获选为敝公司建立下一代Internet气象观测站! 该气象站必须建立在我们专利申请中的WeatherData对象 上,由WeatherData对象负责追踪目前的天气状况(温度、 湿度、气压)。我们希望贵公司能建立一个应用,有三种 布告板,分别显示目前的状况、气象统计及简单的预报。 当WeatherObject对象获得最新的测量数据时,三种布告板 必须实时更新。 而且,这是一个可以扩展的气象站,Weather-O-Rama气象 站希望公布一组API,好让其他开发人员可以写出自己的 气象布告板,并插入此应用中。我们希望贵公司能提供这 样的API。
分析:
此系统中的三个部分是气象站(获取实际气象数据的物理装置)、WeatherData对 象(追踪来自气象站的数据,并更新布告板)和布告板(显示目前天气状况给用 户看)。
WeatherData对象知道如何跟物理气象站联系,以取得更新的数据。WeatherData对 象会随即更新三个布告板的显示:目前状况(温度、湿度、气压)、气象统计和天 气预报。
“目前状况”是三种显示之 一,用户也可以获得气象 统计与天气预报。如果我们选择接受这个项目,我们的工作就是建立一个应用,利用WeatherData对 象取得数据,并更新三个布告板:目前状况、气象统计和天气预报。
实现:
weatherData 继承 Observable类,当参数改变时通知观察者。
import java.util.Observable;
public class WeatherData extends Observable {
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {
}
public void measurementsChanged() {
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;
}
}
显示参数的接口
public interface DisplayElement {
void display();
}
观察者类,实现Displayelement 和 Observer接口
import java.util.Observable;
import java.util.Observer;
public class CurrentConditionsDisplay implements Observer,DisplayElement {
Observable observable;
private float temperature;
private float humidity;
private float pressure;
public CurrentConditionsDisplay(Observable observable) {
this.observable = observable;
observable.addObserver(this);
}
@Override
public void display(){
System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity" + pressure + "%pressure");
}
@Override
public void update(Observable obs, Object arg) {
if (obs instanceof WeatherData) {
WeatherData weatherData = (WeatherData)obs;
this.temperature = weatherData.getTemperature();
this.humidity = weatherData.getHumidity();
this.pressure = weatherData.getPressure();
display();
}
}
}
另一个观察者类
import java.util.Observable;
import java.util.Observer;
public class ForestConditionDIsplay implements Observer,DisplayElement {
Observable observable;
private float temperature;
private float humidity;
private float pressure;
public ForestConditionDIsplay(Observable observable) {
this.observable = observable;
observable.addObserver(this);
}
@Override
public void display(){
System.out.println("Current conditions: " + temperature + "F degrees and " + pressure + "%pressure"+ humidity + "% humidity" );
}
@Override
public void update(Observable obs, Object arg) {
if (obs instanceof WeatherData) {
WeatherData weatherData = (WeatherData)obs;
this.temperature = weatherData.getTemperature();
this.humidity = weatherData.getHumidity();
this.pressure = weatherData.getPressure();
display();
}
}
}
测试类
public class WeatherStation {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay currentDisplay = new
CurrentConditionsDisplay(weatherData);
ForestConditionDIsplay forestConditionDIsplay = new
ForestConditionDIsplay(weatherData);
weatherData.setMeasurements(80, 65, 30.4f);
weatherData.setMeasurements(82, 70, 29.2f);
weatherData.setMeasurements(78, 90, 29.2f);
}
}
结果: