观察者模式
需求
天气预报
- 气象站可以将每天测量到的温度、湿度、气压等等以公告的形式发布出去
- 需要设计开放型api,便于其他第三方也能接入气象站获取数据
- 提供温度、气压、湿度的接口
- 测量数据更新时,要能实时通知给第三方
普通方案
接入方
//显示天气情况(可以理解成网站)
public class CurrentCoditions{
//温度、气压、湿度
private float temperature;
private float pressure;
private float humidity;
//更新,是由WeatherData调用(推送)
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);
}
}
数据提供方
/**
* 核心
* 包含最新的天气情况信息
* 含有CurrentConditions对象
* 当数据有更新时,就主动调用currentConditions的upate方法,这样接入方就看到了最新信息
*/
@Data
public class WeatherData{
private float temperatrue;
private float pressure;
private float humidity;
private CurrentConditions currentConditions;
public WeatherData(CurrentConditions currentConditions){
this.currentConditions = currentConditions;
}
//推送
public void dataChange(){
currentConditions.update(temperatrue,pressure,humidity);
}
//数据更新
public void setData(float temperatrue,float pressure,float humidity){
this.temperatrue = temperatrue;
this.pressure = pressure;
this.humidity = humidity;
dataChange();
}
}
使用
//接入方
CurrentCoditions currentCoditions = new CurrentCoditions();
//提供方
WeatherData weatherData = new WeatherData(currentCoditions);
//更新数据
weatherData.setData(10.0f,10.0f,10.0f);
//更新数据
weatherData.setData(20.0f,20.0f,20.0f);
问题分析
- 其他第三方无法接入
- 无法运行时动态的添加第三方
- 违反了开闭原则(ocp)
观察者模式
对象之间多对一依赖的一种设计方案。被依赖的对象为Subject,依赖的对象为Observer,Subject通知Observer变化
被依赖对象接口
public interface Subject{
//注册
public void registerObserver(Observer o);
//删除
public void removeObserver(Observer o);
//通知
public void notifyObserver();
}
观察者接口
public interface Observer{
//数据改变
public void update(float temperatrue,float pressure,float humidity);
}
接入方,实现观察者接口
//显示天气情况(可以理解成网站)
public class CurrentCoditions 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);
}
}
数据提供方,实现被依赖对象接口
/**
* 核心
* 包含最新的天气情况信息
* 含有Observer观察者集合
* 当数据有更新时,就主动调用currentConditions的upate方法,这样接入方就看到了最新信息
*/
@Data
public class WeatherData implements Subject{
private float temperatrue;
private float pressure;
private float humidity;
private List<Observer> observers;
public WeatherData(){
observers = new ArrayList();
}
//数据更新
public void setData(float temperatrue,float pressure,float humidity){
this.temperatrue = temperatrue;
this.pressure = pressure;
this.humidity = humidity;
//推送给观察者
notifyObserver();
}
@Override
public void registerObserver(Observer o){
observers.add(o);
}
@Override
public void removeObserver(Observer o){
observers.remove(o);
}
@Override
public void notifyObserver(){
for(Observer observer : observers){
observer.update(temperatrue,pressure,humidity);
}
}
}
使用
//被依赖对象
Subject subject = new WeatherData();
//观察者
Observer observer = new CurrentCoditions();
//注册
subject.registerObserver(observer);
//修改
subject.setData(10.0f,10.0f,10.0f);