设计模式-观察者

Posted marton

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式-观察者相关的知识,希望对你有一定的参考价值。

观察者模式

认识观察者模式

订阅报纸的栗子

1)报社的业务是出版报纸

2)你向某家报社订阅他们的报纸,然后你就成为了他们的订阅用户,

   只要报社有新的报纸出版,就会将报纸发送给你

3)当你取消订阅报纸时,你就从报社的订阅用户中删除,报社就不会再发送报纸给你

4)只要报社还在运营,就会一直有人订阅或取消订阅报纸

 

一般我们称上栗中的报社为“主题”,称订阅用户为“观察者”。

1)主题用于管理某些数据,一旦数据发生改变,新的数据就会发送到观察者手中

2)在主题数据发生改变时,只有订阅主题的观察者才能收到更新的数据

3)当新的对象订阅主题时,它会成为一个观察者,它可以收到主题更新的数据

4)当某个观察者取消订阅主题时,它不会再收到主题更新的数据

 主题与观察者的图(待补。。。)

 

观察者模式

概念

定义了对象之间一对多的依赖关系,当一个对象的状态发生改变时,它所有的依赖者都会收到通知并更新数据。

 

UML类图

 技术图片

 

 

UML类图说明

1)主题接口,对象使用此接口注册观察者,删除观察者和更新观察者的状态

2)观察者接口,所有的潜在观察者必须实现此接口,其中只有一个update()方法,当主题状态发生变化时,它将被调用;

  每个主题可以有多个观察者

3)一个具体的主题总是实现主题接口,并实现其注册观察者,删除观察者和更新观察者的状态的方法;

  具体的方法也可以有设置/获取状态的方法。

4)具体的观察者可以是实现观察者接口的任意类,观察者必须注册具体的主题,以便接收和更新数据。

 

设计原则三-为对象之间的松耦合设计而努力

那么说下什么是松耦合

有两个相互依赖的对象,改变其中的一方并不会影响另一方,只要它们的接口仍被遵守,

我们就可以自由的改变它们。

 

主题与观察者之间松耦合,它们可以交互,但是不清楚彼此的细节,

对于观察者,主题只需知道观察者实现了某个接口,并不需要知道观察者的具体类是谁,做了什么等细节

主题唯一依赖的东西是一个实现Observer接口的对象列表,所以我们可以随时增加、删除观察者,用新的观察者取代现有的观察者,

 主题不会受到任何影响。

 

当有新类型的观察者出现时,主题并不需要修改代码

      V

需要做的是新的类型实现此观察者的接口

然后注册成为观察者即可

      V

主题只发送通知给实现此观察者接口的对象

如果我们需要使用观察者和主题,可以轻易的复用它们

 

松耦合的优点

将对象之间的相互依赖降到了最低,能够应对变化,进而可以建立有弹性的面向对象系统。

 

案例

需求

建立一个气象站,该气象站必须建立在我们申请的WeatherData对象上,

由WeatherData对象追踪目前的天气状况(温度,湿度,气压),

有三种布告板,分别显示目前的状况、气象统计和简单的预报,

当WeatherObject对象获得最新的测量数据时,三种布告必须实时更新。

 

分析

WeatherData源文件

技术图片

 

1)通过WeatherData 可以获取三个测量值:温度、湿度和气压

2) 一旦气象测量数据更新,measurementsChanged()方法会被调用

3)需要实现3个使用天气数据的布告板:目前状况布告板、气象统计布告板和天气预报布告板,一旦WeatherData有新的数据,它们立即更新

4)此系统必须可扩展,比如其他开发人员可增加或删除任何布告板

 

有人认为直接把观测值传入观察者中更新状态是最直接的方法,但是这种形式会有很多隐患,

比如,观察者种类的个数可能发生改变,如果这样,我们只能修改更多的代码去满足这些变化,

但是这并不是我们想看到的

参考P57

那么将更新的状态传给观察者,有什么好的解决方案呢?

 

UML类图设计

 技术图片

 

以上是关于设计模式-观察者的主要内容,如果未能解决你的问题,请参考以下文章

java设计模式2-观察者模式

设计模式之观察者模式

[设计模式]观察者模式与订阅模式

设计模式学习总结——观察者模式

玩转设计模式(观察者模式)

玩转设计模式(观察者模式)