观察者模式

时间:2022-12-03 14:06:45

没人疼就去健身,练完浑身疼。

让你的对象,知悉状况

自定义实现观察者模式

Internet气象观测站

观察者模式

应用就是利用WeatherData对象取得传感器数据,并更新三个布告板:目前状况、气象统计和天气预报。

WeatherData

观察者模式

先看一个错误示范

public class WeatherData {
// 实例变量声明

public void measurementsChanged() {
// 取得测量值
float temp = getTemperature();
float humidty = getHumidity();
float pressure = getpRESSURE();

// 调用每个布告板更新显示,传入最新的测量
currentConditionsDisplay.update(temp, humidity, pressure);
statisticsDisplay.update(temp, humidity, pressure);
forecasDisplay.update(temp, humidity, pressure);
}

// 其它方法
}

这样做有什么不对

  1. 违反设计原则,最好是把不变的部分和会改变的东西分别封装起来。

// 调用每个布告板更新显示,传入最新的测量
currentConditionsDisplay.update(temp, humidity, pressure);
statisticsDisplay.update(temp, humidity, pressure);
forecasDisplay.update(temp, humidity, pressure);

这部分可能会改变的东西,可以提出来单独封装。

  1. 针对接口编程,而不是针对实现编程,上面的update()参数都是温度、湿度、气压,看起来像是一个统一的接口。这样针对具体的实现编程,会导致我们以后在增加或删除布告板时必须修改程序。

出版者 + 订阅者 = 观察者模式

观察者模式

定义观察者模式

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

结构类图

观察者模式

松耦合的威力

关于观察者的一切,主题只知道观察者实现了某个接口(也就是Observer接口)。主题不需要知道观察者具体类是谁,做了些什么或其它任何细节。改变主题或观察者其中一方,并不会影响另一方。因为两者是松耦合的,只要他们之间的接口仍被遵守,我们就可以*地改变他们。

设计原则:

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

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

设计气象站

观察者模式

使用Java内置的封装类实现观察者模式

除了自定义接口实现观察者模式,还可以借助Java已经封装好的工具类来实现。

  • 优点:使用上更加方便,甚至可以使用推(push)或拉(pull)的方式传送数据。

  • 缺点:内置的观察者不是一个接口,而是一个类,你要使用的时候只能使用继承,但是java不支持多重继承,你要实现其他类的话,就会陷入矛盾。(而且内置的这套实现已经被官方标记弃用了,所以最好还是使用自定义接口的方式实现,更方便且更有弹性)

tips:

这里面使用了一个setChanged()方法用来标记状态已经改变的事实。有什么用呢?

使得代码更加有弹性,比方说,如果没有setChanged()方法,气象站的测量非常精确,每次温度值有十分之一度就开始更新数据,现在我希望半度以上才更新数据,就可以在温度到达半度时调用setChanged()方法,进行有效的数值更新。

总结

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

代码地址:

https://gitee.com/LHDAXIE/design-mode