1 天气预报需求
气象站可以实时测量当前的温度、湿度等数据并以公告的形式发布出去。现在需要设计一个开放型API接口便于第三个接入并获取到气象站的数据,要求提供温度、湿度的接口,测量的数据要实时通知给第三方。下面我们有观察者模式来实现这个需求。
2 观察者模式介绍
观察者模式是对象之间多对一依赖的一种设计方案,被依赖的对象是Subject,依赖的对象是Observer,Subject通知Observer变化。
角色分析:
Subject:负责登记注册、移出观察者,当有数据变化时,通知到已注册的观察者。
Observer:需要去Subject注册,注册后可以接收到Subject的通知。

观察者模式的类图
3 用观察者模式实现需求
首先定义Subject和Observer:
public interface Subject {
void registerObserver(Observer observer);
void unregisterObserver(Observer observer);
void notifyObservers();
}
// 观察者接口,由观察者实现
public interface Observer {
void update(float temperature, float humidity);
}
气象站实现类WeatherData,实现了Subject:
public class WeatherData implements Subject {
private float temperature;
private float humidity;
// 观察者集合
private List<Observer> observers;
public WeatherData() {
observers = new ArrayList<>();
}
public void setData(float temperature, float humidity) {
this.temperature = temperature;
this.humidity = humidity;
// 更新完数据后通知所有观察者
notifyObservers();
}
public float getTemperature() {
return temperature;
}
public void setTemperature(float temperature) {
this.temperature = temperature;
}
public float getHumidity() {
return humidity;
}
public void setHumidity(float humidity) {
this.humidity = humidity;
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void unregisterObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(temperature, humidity);
}
}
}
观察者实现类有两个,一个是气象站自己的官网,另一个是百度天气:
public class WeatherObserver implements Observer {
private float temperature;
private float humidity;
@Override
public void update(float temperature, float humidity) {
this.temperature = temperature;
this.humidity = humidity;
display();
}
private void display() {
System.out.println("当前温度:" + temperature + ", 湿度:" + humidity);
}
}
public class BaiduObserver implements Observer {
@Override
public void update(float temperature, float humidity) {
System.out.println("百度天气:当前温度:" + temperature + ", 湿度:" + humidity);
}
}
客户端调用:
public class Client {
public static void main(String[] args) {
// 创建一个WeatherData对象
WeatherData weatherData = new WeatherData();
// 创建观察者
Observer observer1 = new WeatherObserver();
Observer observer2 = new BaiduObserver();
// 注册到weatherData中
weatherData.registerObserver(observer1);
weatherData.registerObserver(observer2);
// 天气更新了
System.out.println("===========================");
weatherData.setData(28.5f, 45.0f);
}
}
运行结果:
===========================
当前温度:28.5, 湿度:45.0
百度天气:当前温度:28.5, 湿度:45.0

天气预报需求类图
4 观察者模式的特点
观察者模式会以集合的方式来管理观察者,包括注册、移出和通知,这样的好处是:如果增加观察者,就不需要去修改核心类(WeatherData),符合ocp原则。