设计模式之观察者模式
1. 什么是观察者模式
Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。这样的话就不会错过该对象感兴趣的事情。对象甚至可以在运行时决定是否需要继续被通知。
Observer模式提供给关联对象一种同步通信的手段,使某个对象与依赖它的其他对象之间保持状态同步。
- Subject(被观察者)
被观察的对象。当需要被观察的状态发生变化时,需要通知队列中所有观察者对象。Subject需要维持(添加,删除,通知)一个观察者对象的队列列表。
- ConcreteSubject
被观察者的具体实现。包含一些基本的属性状态及其他操作。
- Observer(观察者)
接口或抽象类。当Subject的状态发生变化时,Observer对象将通过一个callback函数得到通知。
- ConcreteObserver
观察者的具体实现。得到通知后将完成一些具体的业务逻辑处理。
2. 具体实例
首先我有一个Internet的气象站项目:
提供温度、气压和湿度的接口
测量数据更新时需时时通知给第三方
需要设计开放型API,便于其他第三方公司也能接入气象站获取数据
我首先按照面向对象的设计过程,我首先想到的是设计两个类,一个是天气的数据,一个就是公告板也就是对天气的数据进行操作的类
具体实现如下:
CurrentConditions:
1 | public class CurrentConditions { |
WeatherData:
1 | public class WeatherData { |
这样设计带来的问题是什么呢?
1)其他第三方公司接入气象站获取数据的问题
2)无法在运行时动态的添加第三方
也就是说我们想要再添加新的公告板的时候,同时需要更改WeatherData类,这样的话工作量变大,不符合设计要求。
根据上面观察者模式,我们重新设计我们的方案,也就是留出subject和observer两个接口,由WeatherDada和CurrentConditions分别继承实现,这样的话我再来新的公告板的话只需要扩展observer这个接口就可以了。
observer接口:
1 | public interface Observer { |
subject接口:
1 | public interface Subject { |
WeatherDataSt继承自subject,然后observer由ArrayList组成,这样的话每扩展一个公告板就只需要注册Observer就可以了。
1 | public class WeatherDataSt implements Subject { |
公告板
1 | public class ConcurrentConditions implements Observer{ |
这个时候我想要添加一个气象预报的公告板,只需要继承Observer接口然后在WeatherData中注册就可以了
1 | public class ForcastConditions implements Observer{ |
1 | public class InternetWeatherOb { |
通过上面的例子我们可以看出通过观察者模式,我们可以轻松的扩展程序,扩展后只需要让观察者通知被观察者发生的改变即可。
其实观察者模式有两种的实现方式,就是推和拉的模式,推的模式其实就是有主题去通知观察者那些状态发生了改变,拉的方式就是有观察者自己去获取自己需要的状态的改变,对于不需要的不需要获取。
3. java内置的观察者模式
Java内置的观察者:
- Observable
- Observer
接下来通过内置的观察者模式来上面的例子
1 | public class WeatherData extends Observable{ |
1 | public class ConcurrentConditions implements Observer { |
1 | public class InternetWeather { |
其实就是通过继承Java内部的Observable和Observer,实现观察者模式,不用自己去写这俩个接口了。
4. 典型应用
Observer模式的典型应用:
- 侦听事件驱动程序设计中的外部事件
- 侦听/监视某个对象的状态变化
- 发布者/订阅者(publisher/subscriber)模型中,当一个外部事件(新的产品,消息的出现等等)被触发时,通知邮件列表中的订阅者