观察者模式(Observer):定义对象间的一种一对多依赖关系,当一个对象的状态发生改变时,所有依赖于他的对象都得到通知并被自动更新。
场景问题
订阅报纸的问题:
订阅者类向出版者类订阅报纸,很明显不会只有一个订阅者订阅报纸,订阅者类可以有很多;当出版者类出版新报纸的时候,多个订阅者类如何知道呢?还有订阅者类如何得到新报纸的内容呢?
具体描述
|
对应的对象描述
|
解决方案:
使用观察者模式来处理这种问题。观察者模式把这多个订阅者称为观察者:Observer,多个观察者观察的对象被称为目标:Subject
一个目标可以有任意多个观察者对象,一旦目标的状态发生了改变,所有注册的观察者都会得到通知,然后多个观察者会对通知作出相应的响应,执行相应的业务功能处理,并使自己的状态和目标对象的状态保持一致。
观察者模式的结构和说明
- Subject:目标对象,通常具有如下功能。
- 一个目标可以被多个观察者观察
- 目标提供对观察者注册和退订的维护
- 当目标的状态发生变化时,目标负责通知所有注册的、有效的观察者
- Observer:定义观察者的接口,提供目标通知时对应的更新方法,这个更新方法进行相应的业务处理,可以在这个方法里面回调目标对象,以获取目标对象的数据。
- Concrete Subject:具体的目标实现对象,用来维护目标状态,当目标对象的状态发生改变时,通知所有注册的有、有效的观察者,让观察者执行相应的处理
- Concrete Observer:观察者的具体实现对象,用来接收目标的通知,并进行相应的后续处理,比如更新自身的状态以保持和目标的相应装填一致
认识观察者模式
- 目标和观察者之间的关系:目标和观察者之间是典型的一对多的关系
- 单向依赖:在观察者模式中,观察者和目标都是单向依赖的,只有观察者依赖于目标,而目标是不会依赖于观察者的。主动权掌握在目标手中,只有目标知道什么时候需要通知观察者
- 基本的实现说明
- 命名建议
- 观察者模式又被称为发布-------订阅模式
- 目标接口的定义,建议在名称后面跟Subject
- 观察者接口的定义,建议在名称后面跟Observer
- 观察者接口的更新方法,建议名称为Update,当然方法的参数可以根据的需要定义,参数个数不限、参数类型不限
- 触发通知的时机
- 相互观察
- 观察者模式的调用顺序示意图
- 通知的顺序
观察者模式的优缺点
观察者模式具有以下优点:
- 观察者模式实现了观察者和目标之间的抽象耦合
- 原本目标对象在状态发生改变的时候,需要直接调用所有的观察者对象,但是抽象出观察者接口以后,目标和观察者就只是在抽象层面上耦合了,也就是说目标只是知道观察者接口,并不知道具体的观察者的类,从而实现目标类和具体的观察者之间的解耦。
- 观察者模式实现了动态联动
- 所谓联动,就是做一个操作会引起其他相关的操作。由于观察者模式对观察者注册实行管理,那就可以在运行期间,通过动态地控制注册的观察者,来控制某个动作的联动范围,从而实现动态联动。
- 观察者模式支持广播通信
- 由于目标发送通知给观察者是面向所有注册的观察者,所以每次目标通知的信息就要对所有注册的观察者进行广播。当然,也可以通过在目标上添加新的功能来限制广播的范围。
观察者模式的缺点是:
- 可能会引起无谓的操作
思考观察者模式
- 观察者模式的本质:当修改目标对象的状态的时候,就会触发相应的通知,然后会循环调用所有注册的观察者对象的相应方法,其实就相当于联动调用这些观察者的方法。这个联动还是动态的,可以通过这车和取消注册来控制观察者,因而可以在程序运行期间,通过动态地控制观察者,来变相地实现添加和删除某些功能处理,这些功能就是观察者在update的时候执行的功能。同时目标对象和观察者对象的解耦,又保证了无论观察者发生怎样的变化,目标对象总是能够正确地联动过来。
- 何时选用观察者模式
- 当一个抽象模型有两个方面,其中一个方面的操作依赖于另外一个方面的状态变化,那么就可以选用观察者模式,将这两者封装成观察者和目标对象,当目标对象变化的时候,依赖于它的观察着对象也会发生相应的变化。
- 如果在更改一个对象的时候,需要同时连带改变其他的对象,而且不知道究竟有多少对象需要被连带改变,这种情况下可以选用观察者模式,被更改的那一个对象很明显就相当于是目标对象,而需要连带修改的多个其他对象,就作为多个观察者对象了。
- 当一个对象必须通知其他的对象,但是你又希望这个对象和其他被它通知的对象是松散耦合的。
- 观察者模式和状态模式
观察者模式和状态模式是有相似之处的。
观察者模式是当目标状态发生改变时,触发并通知观察者,让观察者去执行相应的操作。而状态模式是根据不同的状态,选择不同的实现,这个实现类的主要功能就是针对状态相应地操作,它不像观察者,观察者本身还有很多其他的功能,接收通知并执行相应处理只是观察者的部分功能。
当然观察者模式和状态模式是可以结合使用的。观察者模式的重心在触发联动,但是到底决定哪些观察者会被联动,这时就可以采用状态模式来实现了,也可以采用策略模式来进行选择需要联动的观察者。
- 观察者模式和中介者模式
观察者模式和中介者模式是可以结合使用的。
如果观察者和被观察的目标之间的交互关系很复杂,比如,有一个界面,里面有三个下拉列表组件,分别选择国家、省份/州、具体的城市,很明显这是一个三级联动,当你选择一个国家的时候,省份/州应该相应改变数据,省份/州一改变,具体的城市也需要相应改变。
concrete
英['kɒŋkriːt] 美['kɑŋkrit]
- adj. 混凝土的;实在的,具体的;有形的
- vi. 凝结
- vt. 使凝固;用混凝土修筑
- n. 具体物;凝结物