- 有一个气象站和多个展示板,在展示板中要更新气象站中的天气信息
public interface Obsever {
// 当气象观察值改变时,把这些状态值作为方法的参数,传给观察者
public void update(float temp, float humidity, float pressure);
}
public interface DisplayElement {
// 展示观察者信息
public void display();
}
两个观察者
观察气温和湿度
public class CurrentConditionsDiaplay implements Obsever, DisplayElement {
private float temprature;
private float humidity;
private Subject weatherData;
public CurrentConditionsDiaplay(Subject weatherData) {// 使用weatherData对象作为注册之用
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override
public void update(float temp, float humidity, float pressure) {
this.temprature = temp;
this.humidity = humidity;
display();
}
@Override
public void display() {
System.out.println("Current conditions:" + temprature
+ "F degrees and " + humidity + " % humidity");
}
}
- 观察气压
public class PressureConditionsDiaplay implements Obsever, DisplayElement {
private float pressure;
private Subject weatherData;
public PressureConditionsDiaplay(Subject weatherData) {// 使用weatherData对象作为注册之用
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override
public void update(float temp, float humidity, float pressure) {
this.pressure = pressure;
display();
}
@Override
public void display() {
System.out.println("pressure conditions:" + pressure);
}
}
- 添加删除观察者接口
public interface Subject {
// 这两个方法要有一个观察者作为变量,该观察者用来注册或删除。
public void registerObserver(Obsever o);
public void removeObserver(Obsever o);
// 当主题状态改变时,这个方法被调用,通知所有观察者
public void notifyObservers();
}
- 提供信息给观察者
import java.util.ArrayList;
//气象站
public class WeatherData implements Subject {
// 存放所有观察者
private ArrayList observers;
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {
observers = new ArrayList<>();
}
// 注册观察者
@Override
public void registerObserver(Obsever o) {
observers.add(o);
}
// 取消观察者
@Override
public void removeObserver(Obsever o) {
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
}
// 给观察者通知更新值
@Override
public void notifyObservers() {
for (int i = 0; i < observers.size(); i++) {
Obsever obsever = (Obsever) observers.get(i);
obsever.update(temperature, humidity, pressure);
}
}
// 当气象站得到更新观察值时,通知观察者
public void measurementsChanged() {
notifyObservers();
}
public void setMeasurements(float temperature, float humidity,
float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
}
}
- 气象站
public class WeatherStation {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionsDiaplay currentConditionsDiaplay = new CurrentConditionsDiaplay(
weatherData);
PressureConditionsDiaplay pressureConditionsDiaplay = new PressureConditionsDiaplay(
weatherData);
weatherData.setMeasurements(30, 20, 30.5f);
weatherData.measurementsChanged();
weatherData.setMeasurements(31, 21, 31.5f);
weatherData.measurementsChanged();
}
}
观察者模式定义了对象之间一对多的关系
被观察者用一个共同接口来更新观察者
有多个观察者时,不可以依赖特定的通知次序
观察者模式:在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。