本文最后更新于:2 个月前
观察者模式
天气预报需求:
- 气象站可以将每天测量到的温度,湿度,气压等一公告的形式发布出去,比如发布到自己的网站或者第三方
- 设计开放性API 便于其他第三方接入气象站获取数据
- 每次更新的时候 就要实时通知其他的第三方更新。
基本介绍
- 观察者模式,对象之间多对一依赖的一种设计方案
代码案例
1 2 3 4 5
| public interface Observer {
public void update(float temperature, float pressure, float humidity); }
|
1 2 3 4 5 6 7
| public interface Subject {
public void registerObserver(Observer o); public void removeObserver(Observer o); public void notifyObservers(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
public class WeatherData implements Subject { private float temperatrue; private float pressure; private float humidity; private ArrayList<Observer> observers;
public WeatherData() { observers = new ArrayList<Observer>(); }
public float getTemperature() { return temperatrue; }
public float getPressure() { return pressure; }
public float getHumidity() { return humidity; }
public void dataChange() { notifyObservers(); }
public void setData(float temperature, float pressure, float humidity) { this.temperatrue = temperature; this.pressure = pressure; this.humidity = humidity; dataChange(); }
@Override public void registerObserver(Observer o) { observers.add(o); }
@Override public void removeObserver(Observer o) { if(observers.contains(o)) { observers.remove(o); } }
@Override public void notifyObservers() { for(int i = 0; i < observers.size(); i++) { observers.get(i).update(this.temperatrue, this.pressure, this.humidity); } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class CurrentConditions implements Observer {
private float temperature; private float pressure; private float humidity;
public void update(float temperature, float pressure, float humidity) { this.temperature = temperature; this.pressure = pressure; this.humidity = humidity; display(); }
public void display() { System.out.println("***Today mTemperature: " + temperature + "***"); System.out.println("***Today mPressure: " + pressure + "***"); System.out.println("***Today mHumidity: " + humidity + "***"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public class Client {
public static void main(String[] args) { WeatherData weatherData = new WeatherData(); CurrentConditions currentConditions = new CurrentConditions(); BaiduSite baiduSite = new BaiduSite(); weatherData.registerObserver(currentConditions); weatherData.registerObserver(baiduSite); System.out.println("通知各个注册的观察者, 看看信息"); weatherData.setData(10f, 100f, 30.3f); weatherData.removeObserver(currentConditions); System.out.println(); System.out.println("通知各个注册的观察者, 看看信息"); weatherData.setData(10f, 100f, 30.3f); }
}
|
观察者模式的好处
- 观察者模式设计后,会以集合的方式来管理用户(Observer),包括注册,移除和通知。
- 这样,我们增加观察者(可以理解为一个新的公告板) 就不需要去修改核心类
WeatherData
,不会修改代码,遵守了OPC
原则。
源码分析
JDK中的Observable类就使用了观察者模式
Spring事件驱动模型就是观察者模式的一个经典应用
监听器就是观察者模式的一种实现