观察者模式:
定义了对象之间的一对多的依赖,当一个对象发生改变时,他的所有依赖对象都会接收通知发生改变。
案例说明:
WeatherData对象负责从气象站获取数据,并将(气温,湿度,气压)同步给多个布告板。
目前有三个布告板。一个布告板负责显示当前当前天气状况,一个负责气象统计,一个负责天气预报,三块布告板都需要Weather提供的(气温,温度,气压数据),才能运作。
![](https://ae01.alicdn.com/kf/Ue33f5475b7c7447dab6ee693c535046f0.jpg)
一个错误设计:
WeatherData有三个从气象站获得数据的方法,detectionMessages检测气象站数据是否更新,然后updateMessages数据及时更新同步到三块布告板上。
![](https://ae01.alicdn.com/kf/U274137bc2b4a47d0904dd9146fa78a76Z.jpg)
我们先不用管数据是如何从气象站获取的,数据又是如何检测的,我们先按照常规思路实现updateMessages();
![](https://ae01.alicdn.com/kf/Uc918c51590d34fb8975ebb37a8163705I.jpg)
我们可以看到使用的方式是调用了每一个布告板的update方法,但如果布告板有很多,就显得代码重复了起来,也不利于布告板的增加或者删除,每次都需要修改源代码,很费力。
接下来采用观察者模式来解决问题:
我们再仔细认识一下观察者模式应用场景:
有一家牛奶厂商(作为主体对象),有很多单位或者个体,向他们订购牛奶,只要他们生产牛奶,然后每天就会派人送牛奶到这些订购的单位或者个体。这些订购的单位可以随时取消订购,也可以随时订购。
分析总结:以上场景和气象站布告板都有同一个点,即形成了一对多的依赖关系,当一个对象发生改变,其依赖的对象都要随之接收通知发生改变。
言归正传,我们重新回到气象站问题,我们重新设计一下类图。
![](https://ae01.alicdn.com/kf/U5fcc661e8b89411b959b70d5ff4ec2f4w.jpg)
气象站作为主体对象,有很多的布告板(依赖对象也叫观察者),所以有registerObserver注册布告板(观察者)方法,removeObserver删除布告板,notifyObservers通知所有的布告板。
我们把主体对象设为接口,使布告板ConcreateObserver(观察者)都实现主体对象的接口update,当主体对象状态发生改变,布告板(观察者)都调用update方法将自身信息进行改变。
详细类图设计:
![](https://ae01.alicdn.com/kf/Ua7517cb0437d4adbb662d171aa0ca5d5X.jpg)
代码实现:
Subject,Observer,Displayment接口:
![](https://ae01.alicdn.com/kf/U321726ac0c684461b9a43c9a35dbd865N.jpg)
Subject接口实现:
![](https://ae01.alicdn.com/kf/Ue0bb36f02b8144d1a4c31af3d37fc7cbl.jpg)
布告板类:
![](https://ae01.alicdn.com/kf/Ub97ef2503ef941329073ab2d43f67246f.jpg)
测试:
![](https://ae01.alicdn.com/kf/Ub181368485c34c92b261478b8ca9b8daS.jpg)