设计模式:观察者模式(Observer)
来源:互联网 发布:怎么禁止软件发短信 编辑:程序博客网 时间:2024/05/12 04:04
定义对象见的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
观察者模式的角色
1. 抽象主题角色(Subject):把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
2. 具体主题角色(ConcreteSubject):在具体主题内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个子类实现。
3. 抽象观察者角色(Observer):为所有的管擦着定义一个接口,在得到主题的通知更新自己。
4. 具体观察者角色(ConcreteObserver):该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态和主题的状态相协调。通常用一个子类实现。如果需要,具体观察者角色可以保持一个指向具体主题角色的引用。
举个简单案例:
1 抽象观察者角色(Observer):
- 1
- 2
- 3
- 4
2 抽象主题角色(Subject)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
3 具体主题角色(ConcreteSubject)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
4 具体观察者角色(ConcreteObserver)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 测试代码:
- 1
- 2
- 3
- 4
输出结果:
- 1
- 2
推模型和拉模型
在观察者模式中,又分为推模型和拉模型两种方式。
1. 推模型:主题对象向观察者推送主题的详细信息,不管观察者是否需要,推送的信息通常是主题对象的全部或部分数据。
2. 拉模型:主题对象在通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,由观察者主动到主题对象中获取,相当于是观察者从主题对象中拉数据。一般这种模型的实现中,会把主题对象自身通过update()方法传递给观察者,这样在观察者需要获取数据的时候,就可以通过这个引用来获取了。
将上面的代码修改一下,变为拉模型案例:
1 抽象观察者角色Observer2,通常是把主题对象当做参数传递
- 1
- 2
- 3
- 4
2 具体观察者角色
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
3 抽象主题角色
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
4 具体主题角色
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
测试代码:
- 1
- 2
- 3
- 4
输出结果:(同上一个案例)
两种模式比较:
- 推模型假定主题对象知道观察者需要的数据;而拉模型是主题对象不知道观察者具体需要什么数据,没有办法的情况下,干脆把自身传递给观察者,让观察者自己取按需要取值。
- 推模型可能会使得观察者对象难以复用,因为观察者的update()方法是按需要定义的参数,可能无法兼顾没有考虑到的使用情况。这就意味着出现新情况的时候,就可能提供新的update()方法,或者是干脆重新实现观察者;而拉模型就不会造成这样的情况,因为拉模型下,update()方法的参数是主题对象本身,这基本上是主题对象能传递的最大数据集合了,基本上可以适应各种情况的需要。
优缺点
优点:
1. Subject和Observer之间是松耦合的,分别可以各自独立改变。
2. Subject在发送广播通知的时候,无需指定具体的Observer,Observer可以自己决定是否要订阅Subject的通知。
缺点:
1. 松耦合导致代码关系不明显,有时可能难以理解
2. 如果一个Subject被大量Observer订阅的话,在广播通知的时候可能会有效率问题。
适用场景
1. 对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态改变。
2. 对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节。
JDK中的观察者模式:
java.util.EventListener
javax.servlet.http.HttpSessionBindingListener
javax.servlet.http.HttpSessionAttributeListener
javax.faces.event.PhaseListener
参考资料
1. 《23种设计模式》
2. 《细数JDK里的设计模式》
3. 《《JAVA与模式》之观察者模式》
- 设计模式--观察者(Observer)
- 设计模式-观察者(Observer)
- 观察者设计模式(Observer)
- Observer(观察者)设计模式
- 观察者设计模式Observer
- 观察者设计模式(observer)
- observer(观察者设计模式)
- Observer(观察者)设计模式
- 设计模式之Observer(观察者模式)
- 设计模式之Observer(观察者模式)
- 设计模式 (十五)观察者模式(Observer)
- 设计模式 (十五)观察者模式(Observer)
- 【设计模式】之观察者模式(Observer)
- 设计模式之--观察者模式(Observer)
- 设计模式(二)Observer - 观察者模式
- 设计模式之观察者(Observer)模式
- 设计模式之观察者(observer)模式
- 设计模式学习--观察者模式(observer)
- 设计模式:备忘录模式(Memento)
- php代码编写规范
- 嵌入式物联网应用开发-远程温度监控
- LeetCode进阶之路(N-Queens)
- VPS安全之iptables基本配置
- 设计模式:观察者模式(Observer)
- activiti-rest的权限控制
- NOI2012 美食节 动态加边维护费用流
- 第2章 获得文本语料和词汇资源
- Myeclipse中weblogic配置
- Q48:不能被继承的类 ——学习笔记
- 第九届湖南省大学生程序设计竞赛部分题解
- LeetCode 166. Fraction to Recurring Decimal
- UVA - 216 Getting in Line