设计模式摘要(核心篇)二、观察者模式

定义:在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。

模式类图

作用

帮助对象知悉状况,不会错过该对象感兴趣的事。对象可以在运行时决定是否要继续被通知。观察者模式是 JDK 中使用最多的模式之一,非常有用。

注意点

一对多关系

“一个”主题对应“多个”观察者的关系。主题是真正拥有数据的人,观察者是主题的依赖者,在数据变化时更新,这样比起让许多对象控制同一份数据来,可以得到更干净的 OO 设计。

松耦合

当两个对象之间松耦合,它们依然可以交互,但是不太清楚彼此的细节。

  • 关于观察者的一切,主题只知道观察者实现了某个接口(也就是 Observer 接口)。主题不需要知道观察者的具体类是谁、做了些什么或其他任何细节。
  • 任何时候我们都可以增加新的观察者,或删除某些观察者,主题不会受到任何影响。
  • 有新类型的观察者出现时,主题的代码不需要修改。
  • 我们可以独立地复用主题或观察者。
  • 改变主题或观察者其中一方,并不会影响另一方。只要它们之间的接口仍被遵守,我们就可以自由地改变他们。

松耦合的设计之所以能让我们建立有弹性的 OO 系统,能够应对变化,是因为对象之间的互相依赖降到了最低。

OO 原则

  • 为了交互对象之间的松耦合设计而努力

其他

  • 数据可以由主题向观察者“推送”;也可由观察者向主题“拉取”。
  • Java 内置的观察者模式中,有一个 setChanged() 方法,标记状态已经改变。这样做有其必要性。如果没有 setChanged() 方法,由于气象站温度计足够灵敏,可能每十分之一度就会更新,这会造成 WeatherData 对象持续不断地通知观察者。如果我们希望半度以上才更新,就可以在温度差距到达半度时,调用 setChanged(),进行有效的更新。
  • Java 内置的观察者模式违背了一些设计原则,不够灵活。可以考虑采用自己的实现

模式应用

场景

气象观测站。写一个 app,利用 WeatherData 对象取得数据,并更新三个布告板:目前状况、气象统计和天气预报。

应用类图

参考代码:观察者模式