本文根据尚硅谷韩顺平老师的设计模式课程编写设计模式
项目需求
- 气象站可以将每天测量到的温度,湿度,气压等等以公告的形式发布出去(比如发布到自己的网站或第三方)。
- 需要设计开放型API,便于其他第三方也能接入气象站获取数据。
- 提供温度、气压和湿度的接口
- 测量数据更新时,要能实时的通知给第三方
传统方式问题分析
- 其他第三方接入气象站获取数据的问题
- 无法在运行时动态的添加第三方
原理
观察者模式:对象之间多对一依赖的一种设计方案,被依赖的对象为Subject,依赖的对象为Observer, Subject通 知Observer变化,比如这里的网站是Subject,是1的一方。用户是Observer,是多的一方。
代码
public class CurrentConditions implements Observer {
//温度,气压,湿度
private float temperature;
private float pressure ;
private float humidity;
//更新天气情况,是由WeatherData来调用,我使用推送模式
@Override
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("温度:"+temperature);
System.out.println("气压:"+pressure);
System.out.println("湿度:"+humidity);
}
}
public interface Observer {
public void update(Float temperature,Float pressure, Float humidity);
}
//让WeaterData来实现
public interface Subject {
public void registerObserver(Observer observer);
public void removeObserver(Observer observer);
public void notifyObserver();
}
public class WeatherData implements Subject {
private float temperature;
private float pressure ;
private float humidity;
//观察者集合
private ArrayList<Observer> observers;
public WeatherData() {
observers = new ArrayList<>();
}
public float getTemperature() {
return temperature;
}
public void setTemperature(float temperature) {
this.temperature = temperature;
}
public float getPressure() {
return pressure;
}
public void setPressure(float pressure) {
this.pressure = pressure;
}
public float getHumidity() {
return humidity;
}
public void setHumidity(float humidity) {
this.humidity = humidity;
}
public void dataChange(){
notifyObserver();
}
public void setData(Float temperature, Float pressure, Float humidity){
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
dataChange();
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObserver() {
//遍历所有的观察者并通知
observers.forEach(observer -> {
observer.update(this.temperature,this.pressure,this.humidity);
});
}
}
public class Client {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditions currentConditions = new CurrentConditions();
weatherData.registerObserver(currentConditions);
//通知各个注册的观察者
weatherData.setData(10f,20f,20f);
}
}
源码
JDK中的Observable使用到了观察者模式