设计模式系列教程—Observer Pattern(观察者模式)

2 Observer Pattern(观察者模式)

2.1设计原则一

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

下面举个例子说明这个原则。

1)案例分析一:

REQ1:Vander接到一个外包的项目,项目是关于下一代Internet的气象观测站,此系统中三个部分是气象站(获取实际气象数据的物理装置),WeatherData对象(追踪来自气象站的数据,并更新布告板)和布告板(显示目前天气状况给用户看)。

image

Vander的工作就是建立一个应用,利用WeatherData对象取得数据,并更新是三个布告板:目前状况、气象统计、天气预报。

委托方发送过来的WeatherData类:

image

所以Vander的工作就是完成measurementsChanged这个方法,好让它更新目前状况、气象统计和天气预报的显示布告板。

解决方法1:Vander 就开始设计了

image
public void measurementsChanged() {

      currentConditionDisplayer.update(temperature, humidity, pressure);

      forecastDisplayer.update(temperature, humidity, pressure);

      statisticDisplayer.update(temperature, humidity, pressure);

   }

这个方法出现了以下4个问题:
1、针对实现编程而不是针对接口编程:首先更新数据的这个操作都是这三个布告板自己完成的,而不是由第三者来帮助完成(回想鸭子飞行的实现方法,鸭子飞行是由专门的飞行类来完成的,而不是由鸭子本身来实现的,鸭子本身只是调用了飞行类)。
2、对于每个新的布告板,都需要修改WeatherData这个类。
3、无法动态添加或者删除布告板:即每次增加删除布告板都需要重新运行程序
4、没对变化的部分进行封装:WeatherData会因为布告板的增加减少而改变,要针对这样的改变进行一定的封装

解决方法2 观察者模式:

image

Vander听说了观察者模式之后使用观察者模式进行设计,先说明一下观察者模式,实际上就是发布-订阅模式,简单举个例子,Vander和Pander和Triangle三个人一起订了杂志,每天杂志社都会给他们推送杂志,有一天Triangle不想订杂志了,跟杂志社取消订阅,然后Triangle就不会收的杂志了,而Vander跟Panda继续收到杂志,Triangle发现没有杂志的日子太无聊了,所以又去订阅杂志,于是他又能收到杂志了。实际上发布-订阅模式,就是一种推数据的方式,由主题者(发布者)将数据推给观察者(订阅者)。

上图中的做法实际上就是让主题者在更新消息的同时然后帮观察者调用观察者的update方法。

解决方法3(使用Java api的观察者):


image

注意Java Api的方式有一定的局限性,首先Observable是作为父类的,所以子类的WeatherData要成为主题者只能继承Observable,Observable实现的notifyObservers方法中需要先调用setChanged方法,这样子是为了保证不是每次更新数据都去通知布告板,但是Observable的setChanged方法是用protected保护起来了,这就意味着需要子类继承Observable才能调用setChanged方法,这也就违反了第三条原则“多用组合,少用继承”。

面向对象基础

抽象、封装、多态、继承

四大原则

设计原则一:封装变化

设计原则二:针对接口编程,不针对实现编程。

设计原则三:多用组合,少用继承。

设计原则四:为交互对象之间的松耦合设计而努力

模式

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

你可能感兴趣的:(设计模式系列教程—Observer Pattern(观察者模式))