场景
气象站发布 和 更新 天气信息,第三方站点 获取的过程。
思路_1:
第三方站点主动去调用气象站的数据。
表面上看没什么问题,但从具体情况出发就会显得略显不妥。
第三方只能定时的去获取,这可能会不准确,也可能会浪费系统资源。
因为第三方无法知道气象站的更新时间
思路_2:
气象站主动给第三方推送。
这样似乎解决了思路_1的问题,但有出现了新的问题:
如果要想让气象站推送的话,那么第三方站点就需要被气象站维护。
换言之,就是气象站类依赖于第三方站点类。
这样的话,当第三方站点数量和种类情况发生变化时,就会影响到 气象站类。
气象站类 是核心类,这样随便改的话,显然破坏了 开闭原则,违背了 高内聚,低耦合 的设计思想。
这便引出了我们的常用设计模式之一:
观察者模式
先看图:
再听我解释:
为了解决 第三方站点类的变换情况对 核心类(WeatherStations)的影响,我们可以利用一个数组,将第三方站点类 规整起来传给核心类(WeatherStations) 统一维护,这样就把 气象站类对第三方站点类的依赖转换成了 对数组的依赖。
由于第三方站点类存在差异性,所以我们利用 Observer 接口 将其统一。
让 WeatherStations 去依赖 Observer,这样就统一了。
核心就两点:
- 利用数组解决 第三方站点类的数量和种类的变化性带来的问题
- 利用接口统一 第三方站点类的差异性问题。
来看看代码吧!:
Code
观察者接口:
public interface Observer {
//更新天气温度
public void update(int temperature);
}
BaiDu:
public class BaiDu implements Observer{
private int temperature;
@Override
public void update(int temperature) {
this.temperature = temperature;
}
public int getTemperature(){
System.out.println("百度获取温度如下:");
return temperature;
}
}
Jd:
public class Jd implements Observer{
private int temperature;
@Override
public void update(int temperature) {
this.temperature = temperature;
}
public int getTemperature(){
System.out.println("京东获取温度如下:");
return temperature;
}
}
他们两个都实现了观察者接口,体现了他们的观察者身份。
核心类接口:
public interface Subject {
//注册观察者
public void addObserver(Observer observer);
//移除观察者
public void removeObserver(Observer observer);
}
WeatherStations类:
/**
* 气象站
*/
public class WeatherStations implements Subject{
private int temperature;
private List<Observer> list = new ArrayList<>();
//设置温度(气象站测出了温度)
public void setTemperature(int temperature){
this.temperature = temperature;
//给第三方城市推送
if (!list.isEmpty()){
for(Observer observer:list){
observer.update(temperature);
}
}
}
//获取温度
public int getTemperature(){
return temperature;
}
@Override
//添加观察者
public void addObserver(Observer observer) {
list.add(observer);
}
@Override
//移除观察者
public void removeObserver(Observer observer) {
list.remove(observer);
}
}
WorkTest(客户端类):
public class WorkTest {
public static void main(String[] args) {
//创建气象站
WeatherStations stations = new WeatherStations();
//创建第三方
BaiDu baiDu = new BaiDu();
Jd jd = new Jd();
//将第三方(观察者)加入维护到 气象站中(注册)
stations.addObserver(baiDu);
stations.addObserver(jd);
//移除第三方(解除合约)
stations.removeObserver(jd);
//设置天气温度并推送
stations.setTemperature(8);
//第三方 打印自己获取的天气温度
System.out.println(baiDu.getTemperature());
System.out.println(jd.getTemperature());
}
}
运行结果
百度获取温度如下:
8
京东获取温度如下:
0
首先创建了气象站类,并将两个第三方站点注册了进去,又把京东站点移除了。