让你的对象,知悉状况
自定义实现观察者模式
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);
}
// 其它方法
}
这样做有什么不对
-
违反设计原则,最好是把不变的部分和会改变的东西分别封装起来。
// 调用每个布告板更新显示,传入最新的测量
currentConditionsDisplay.update(temp, humidity, pressure);
statisticsDisplay.update(temp, humidity, pressure);
forecasDisplay.update(temp, humidity, pressure);
这部分可能会改变的东西,可以提出来单独封装。
-
针对接口编程,而不是针对实现编程,上面的update()参数都是温度、湿度、气压,看起来像是一个统一的接口。这样针对具体的实现编程,会导致我们以后在增加或删除布告板时必须修改程序。
出版者 + 订阅者 = 观察者模式
定义观察者模式
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
结构类图
松耦合的威力
关于观察者的一切,主题只知道观察者实现了某个接口(也就是Observer接口)。主题不需要知道观察者具体类是谁,做了些什么或其它任何细节。改变主题或观察者其中一方,并不会影响另一方。因为两者是松耦合的,只要他们之间的接口仍被遵守,我们就可以*地改变他们。
设计原则:
为了交互对象之间的松耦合设计而努力。
松耦合的设计之所以能让我们建立有弹性的OO
系统,能够应对变化,是因为对象之间的互相依赖降到了最低。
设计气象站
使用Java内置的封装类实现观察者模式
除了自定义接口实现观察者模式,还可以借助Java已经封装好的工具类来实现。
-
优点:使用上更加方便,甚至可以使用推(push)或拉(pull)的方式传送数据。
-
tips:
这里面使用了一个setChanged()
方法用来标记状态已经改变的事实。有什么用呢?
使得代码更加有弹性,比方说,如果没有setChanged()
方法,气象站的测量非常精确,每次温度值有十分之一度就开始更新数据,现在我希望半度以上才更新数据,就可以在温度到达半度时调用setChanged()
方法,进行有效的数值更新。
总结
观察者模式——在对象之间定义一对多的依赖,这样一来,当一个对象改变状态依赖它的对象就会收到通知,并自动更新。
代码地址: