找回密码
 立即注册
首页 业界区 业界 《Head First设计模式》读书笔记 —— 观察者模式 ...

《Head First设计模式》读书笔记 —— 观察者模式

轩辕琳芳 前天 20:35
《Head First设计模式》读书笔记
相关代码:Vks-Feng/HeadFirstDesignPatternNotes: Head First设计模式读书笔记及相关代码

  • 让你的对象知悉现状,不会错过对象感兴趣的事
  • 对象甚至在运行时可决定是否要继续被通知
  • JDK中使用最多的模式之一
本节例子

1.png

系统三部分:

  • 气象站:获取实际气象数据的物理装置
  • WeatherData对象(追踪来自气象站的数据,并更新布告板)
  • 布告板:显示目前天气状况给用户看
物理气象站→WeatherData对象(已完成)
WeatherData对象→及时更新布告板
我们的工作:建立一个应用,利用WeatherData对象取得数据,并更新三个布告板(目前状况、气象统计、天气预报)
  1. |-----------------------|
  2. |      WeatherData      |
  3. |-----------------------|
  4. |   getTemperature()    |
  5. |   getHumidity()       |
  6. |   getPressure()       |
  7. |   measure-            |
  8. |   mentsChanged()      |
  9. |   //其他方法           |
  10. |-----------------------|
复制代码
一旦气象测量更新,mentsChanged会被调用
错误示范
  1. public class WeatherData {
  2.         public void measurementsChanged() {
  3.                 float temp = getTemperature();
  4.                 float humidity = getHumidity();
  5.                 float pressure = getPressure();
  6.                 currentConditionDisplay.update(temp, humidity, pressure);
  7.                 statisticsDisplay.update(temp, humidity, pressure);
  8.                 forecastDisplay.update(temp, humidity, pressure);
  9.         }
  10. }
复制代码
认识观察者模式

报纸类比:

  • 报社的业务就是出版报纸
  • 向报社订阅报纸,当有新报纸出版时,就会送来。只要是订户,就会一直收到报纸
  • 不再想看时,取消订阅,就不会再送
  • 只要报社还运行,就会一直有人向他们订阅/取消订阅
出版者+订阅者=观察者模式

HeadFirst设计模式2-观察者模式
出版者↔️主题(subject)
订阅者↔️观察者(Observer)
2.png

观察者模式使用


  • 对象告知主题,想要成为观察者 —— 注册(订阅)
  • 对象成为观察者,可以接收到通知
  • 对象要求从观察者把自己除名(取消订阅),主题接收到请求,将其除名
定义观察者模式

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。


  • 定义了一系列对象之间的一对多关系
  • 状态改变→依赖者都会接到通知
类图

3.png

Q&A

Q:这和一对多的关系有何关联?
A:利用观察者模式,主题是具有状态的对象,并且可以控制这些状态,也就是说,有“一个”具有状态的主题。另一方面,观察者使用这些状态,虽然这些状态并不属于他们,有许多的观察者,以来主题来告诉他们状态何时改变了。这就产生了一个关系:“一个”主题对“多个”观察者的关系。
Q:其间的依赖是如何产生的?
A:主题是真正拥有数据的人,观察者是主题的依赖者,在数据变化时更新,这样比起让许多对象控制同一份数据来,可以得到更干净的OO设计。
松耦合的威力

当两个对象之间松耦合,它们依然可以交互,但是不太清楚彼此的细节。
观察者模式提供了一种对象设计,让主题和观察者之间松耦合。

  • 主题唯一依赖的东西就是一个实现Observer接口的对象列表,所以我们怎么操作其中的观察者对象(增删改),不会影响到主题。
  • 当有新类型的观察者出现时,不需要修改主题的代码,只需要该类去实现观察者接口,然后注册为观察者即可。主题不在乎别的,只会发送给所有实现了观察者接口的对象。
  • 可以独立地复用主题或观察者,其他地方需要使用时也可以轻易地复用,因为二者并非紧耦合
  • 因为主题和观察者二者是松耦合的,所以只要它们之间的接口仍被遵守,就可以自由地改变它们
设计原则4 :为了交互对象之间的松耦合设计而努力
松耦合的设计之所以能让我们建立有弹性的OO系统,能够应对变化,是因为对象之间的相互依赖降到了最低
气象站设计

4.png

“拉”与“推”之辩

拉:指观察者主动向主题获取数据
推:指主题将信息发给观察者
“拉”:

  • 拉的好处:

    • 主题不可能事先料到各种观察者的需求,拉可以让各种观察者去获取目标信息,而非被动接收到一大坨信息(其中可能包含不需要的内容)
    • 当主题需要扩展功能时,不用修改和更新对每位观察者的调用,只需要改变自己的getter、setter即可

  • 拉的缺点:

    • 主题必须门户大开,封装性被打破,面临被大肆挖掘数据的风险
    • 观察者可能会多次调用才能拼凑其所需信息

“推”:与“拉”的优缺相对应,略
Java内置的观察者模式


( Java 9 及更高版本中,Observable 类被标记为 @Deprecated,意味着它仍然可以使用,但不推荐使用,未来可能会被移除。)
当然,我们还是可以从中学到一些东西的
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册