设计模式—— 观察者模式

Posted 玛丽莲茼蒿

tags:

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

问题描述

        我们收到了Weahter-O-Rama公司(相当于艾睿公司)提供的一个demo,可以看出通过Weahter-O-Rama公司提供的SDK,WeahterData可以直接调用getter方法获取温度、湿度、气压数据,并提供了一个让我们自己去写的回调函数measurementsChanged()

 观察者模式

观察者模式

观察模式= 出版者(publish)+订阅者(subscribe)

观察者模式定义了对象之间的多对一依赖,这样一来,当出版者的状态改变时,它的所有依赖者(订阅者)都会收到消息并自动更新。

观察者模式类图模板 

用观察者模式实现WeatherData

 

WeatherData类和公告板类之间通过什么关系通信呢?

        我们知道两个类之间的关系耦合度由强到弱分别是:继承|实现→组合→聚合→关联→依赖,我们既想要实现低耦合又要选择符合实际的关系。

        WeatherData作为一个发布者,是有义务知道所有的订阅者都是谁的,所以要把订阅者们作为其成员变量保存起来,这样才能方便通知他们,也就是通过组合的关系。

        公告板类依赖WeatherData类对其进行消息的推送,需要在自己的构造器中用到WeatherData类的注册方法,这样我们用依赖关系就够了。但是例子用的依然是组合关系,给出的解释是下图这样的,意思是将WeatherData类作为成员变量更方便进行注册和注销操作(看来用组合关系和用依赖关系对耦合性影响不大,别用继承关系就行了)。

关于使用DisplayElement接口的解释:   

        对于每个公告板,display()方法展出的内容都不同,每个公告板都要重写自己的display()方法。通过继承抽象类也能实现这一功能,但是继承的目的是实现代码复用,这里显然display()无法复用,那我们直接使用接口interface。    

        还记得吗,在策略模式中,我们将display()方法作为Duck这个抽象类的成员方法,然后各个鸭子子类通过继承Duck的方式去重写display()方法。其实当时display()方法也可以单独拿出来作为一个接口interface DisplayElement,让所有鸭子子类implements这个接口然后重写,其实是一样的。但是因为鸭子还有swim等共同的行为,需要用继承的方式去进行代码复用,那么我们的display()方法就“顺势索性”直接写在抽象类里了。

        

完整代码如下

各个接口:

WeatherData.java

注意思考,原本Weather-O-Data公司提供的demo里,有三个getter方法。这里没有写是因为什么?答案同图中最后一块代码出现的原因,因为我们根本没有Weather-O-Data公司提供的气象站和SDK,所以只能手动输入观测的数据,我们这不是在模拟嘛。

 公告板.java

 

测试类.java

 

 

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

设计模式第二篇-观察者模式

设计模式-观察者模式

设计模式-观察者模式

设计模式-观察者模式

设计模式之观察者模式

设计模式之观察者模式