文章目录

  • 天气预报项目需求,具体要求如下
    • 天气预报设计方案 – 普通方案
      • 问题分析
    • 观察者模式
      • debug下去看一下
      • 观察者模式的好处
      • 观察者模式在Jdk 应用的源码分析

天气预报项目需求,具体要求如下

  1. 气象站可以将每天测量到的温度,湿度,气压等等以公告的形式发布出去(比如发布到自己的网站或第三方)。
  2. 需要设计开放型 API,便于其他第三方也能接入气象站获取数据。
  3. 提供温度、气压和湿度的接口
  4. 测量数据更新时,要能实时的通知给第三方

天气预报设计方案 – 普通方案

传统的设计方案

CurrentConditions类, 显示当前天气情况(可以理解成是气象站自己的网站)

WeatherData类

  1. 包含最新的天气情况信息
  2. 含有 CurrentConditions 对象
  3. 当数据有更新时,就主动的调用 CurrentConditions对象update方法(含 display), 这样他们(接入方)就看到最新的信息

客户端类

就是将网站类(CurrentConditions)注册到气象站类(WeatherData)

一旦有数据变化则调用网站的输出方法

问题分析

  1. 其他第三方接入气象站获取数据的问题
  2. 无法在运行时动态的添加第三方 (新浪网站)
  3. 违反 ocp 原则(“开-闭原则”,一个软件应该对扩展开放,对修改关闭)
  4. 在 WeatherData 中,当增加一个第三方,都需要创建一个对应的第三方的公告板对象,并加入到 dataChange, 不利于维护,也不是动态加入

需要改变的地方

所以引出了我们的观察者模式

气象局:Subject
第三方网站:Observer

Subject:登记注册、移除和通知

  1. registerObserver 注册
  2. removeObserver 移除
  3. notifyObservers() 通知所有的注册的用户,根据不同需求,可以是更新数据,让用户来取,也可能是实施推送, 看具体需求定

Observer:接收输入

观察者模式

对象之间多对一依赖的一种设计方案,被依赖的对象为 Subject,依赖的对象为 Observer,Subject
通知 Observer 变化,比如这里的网站是 Subject,是 1 的一方。用户是 Observer,是多的一方。

CurrentConditions类

还是上面的类,只不过需要实现Observer接口

Observer接口

Subject接口

统一定义了方法, 让WeatherData 来实现


WeatherData类实现Subject接口,包含最新的天气情况信息 ,含有 观察者集合,使用ArrayList管理
当数据有更新时,就主动的调用 ArrayList, 通知所有的(接入方)就看到最新的信息

客户端类

看运行结果是跟上面一样的

但是我们如果现在又新增了一个网站BaiduSite

我们只需要实现Observer接口,然后在客户端里面注册进去就好了

这样我们的气象站类不需要改变任何代码!

debug下去看一下

首先注册了两个网站

进入setData方法,给自己的属性赋值

调用dataChange

调用notifyObservers方法

再调用CurrentConditions的update方法

赋值后调用输出方法


流程完毕!!

观察者模式的好处

  1. 观察者模式设计后,会以集合的方式来管理用户(Observer),包括注册,移除和通知。
  2. 这样,我们增加观察者(这里可以理解成一个新的公告板),就不需要去修改核心类 WeatherData 不会修改代码, 遵守了 ocp 原则。

观察者模式在Jdk 应用的源码分析

  1. Jdk 的 Observable 类就使用了观察者模式
  2. 代码分析+模式角色分析

Observable类

他也有增、删、通知方法


3.模式角色分析

Observable 的作用和地位等价于 我们前面讲过 Subject,Observable 是类,不是接口,类中已经实现了核心的方法 ,即管理 Observer 的方法 add… delete … notify…,Observer 的作用和地位等价于我们前面讲过的 Observer, 有 update

Observable 和 Observer 的使用方法和前面讲过的一样,只是 Observable 是类,通过继承来实现观察者模式

如果用jdk中自带的Observable类改造我们上面的需求就是这样的

CurrentConditions类,实现jdk的Observer

WeatherData类,继承jdk的Observable类

BaiduSite类,另外一个网站

客户端类,老样子

运行结果

资料参考:https://www.bilibili.com/video/BV1G4411c7N4

代码地址:https://gitee.com/WangFuGui-Ma/design-pattern/tree/master/design