设计模式——观察者模式详解(边边奋斗史)

场景

气象站发布 和 更新 天气信息,第三方站点 获取的过程。

思路_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

首先创建了气象站类,并将两个第三方站点注册了进去,又把京东站点移除了。

That’s all,Thank you !!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

少歌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值