- 浏览: 33318 次
- 性别:
- 来自: 上海
最新评论
GoF说道:Observer模式的意图是“定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新”。
适用性
1.当一个抽象模型有两个方面,其中一个方面依赖于另一方面。
将这二者封装到独立的对象中以使它们可以各自独立地改变和复用。
2.当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。
3.当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望
这些对象是紧密耦合的。
参与者
.抽象主题(Subject)角色:主题角色把所有的观察者对象的引用保存在一个列表里;
每个主题都可以有任何数量的观察者。主题提供一个接口可以加上或撤销观察者对象;主题角
色又叫做抽象被观察者(Observable)角色;
. 抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到通知时更新自己;
. 具体主题(ConcreteSubject)角色:保存对具体观察者对象有用的内部状态;在这
种内部状态改变时给其观察者发出一个通知;具体主题角色又叫作具体被观察者角色;
.具体观察者(ConcreteObserver)角色:保存一个指向具体主题对象的引用;和一
个与主题的状态相符的状态。具体观察者角色实现抽象观察者角色所要求的更新自己的接口,
以便使本身的状态与主题的状态自恰。
示例代码:
1.抽象主题角色类
2.抽象观察者角色
3.具体主题角色(Watched)
4.具体观察者角色(Watcher)
5.客户端调用:
执行结果为:
推模型和拉模型
在观察者模式的实现里面,又分为推模型和拉模型两种方式。
推模型
目标对象主动向观察者推送目标的详细信息,不管观察者是否需要,推送的信息通常是目
标对象的全部或部分数据,相当于是在广播通信。实现方法就是,update 方法加一个参
数,通过这个参数把数据传过去。
拉模型
目标对象在通知观察者的时候,只传递少量信息,如果观察者需要更具体的信息,由观察
者主动到目标对象中获取,相当于是观察者从目标对象中拉数据。
一般这种模型的实现中,会把目标对象自身通过update方法传递给观察者,这样在观察者
需要获取数据的时候,就可以通过这个引用来获取了。
观察者模式的优缺点
观察者模式实现了观察者和目标之间的抽象耦合
原本目标对象在状态发生改变的时候,需要直接调用所有的观察者对象,但是抽象出观察者接
口过后,目标和观察者就只是在抽象层面上耦合了,也就是说目标只是知道观察者接口,并不
知道具体的观察者的类,从而实现目标类和具体的观察者类之间解耦。
观察者模式实现了动态联动
所谓联动,就是做一个操作会引起其它相关的操作。由于观察者模式对观察者注册实行管
理,那就可以在运行期间,通过动态的控制注册的观察者,来控制某个动作的联动范围,从而
实现动态联动。
观察者模式支持广播通信
由于目标发送通知给观察者是面向所有注册的观察者,所以每次目标通知的信息就要对所有注
册的观察者进行广播。当然,也可以通过在目标上添加新的功能来限制广播的范围。
在广播通信的时候要注意一个问题,就是相互广播造成死循环的问题。比如A和B两个对象
互为观察者和目标对象,A对象发生状态变化,然后A来广播信息,B对象接收到通知后,在处
理过程中,使得B对象的状态也发生了改变,然后B来广播信息,然后A对象接到通知后,又触
发广播信息……,如此A引起B变化,B又引起A变化,从而一直相互广播信息,就造成死循环
了。
观察者模式可能会引起无谓的操作,降低性能
由于观察者模式每次都是广播通信,不管观察者需不需要,每个观察者都会被调用update方
法,如果观察者不需要执行相应处理,那么这次操作就浪费了。
增加了复杂度,容易引起误操作。死循环等。
适用性
1.当一个抽象模型有两个方面,其中一个方面依赖于另一方面。
将这二者封装到独立的对象中以使它们可以各自独立地改变和复用。
2.当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。
3.当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望
这些对象是紧密耦合的。
参与者
.抽象主题(Subject)角色:主题角色把所有的观察者对象的引用保存在一个列表里;
每个主题都可以有任何数量的观察者。主题提供一个接口可以加上或撤销观察者对象;主题角
色又叫做抽象被观察者(Observable)角色;
. 抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到通知时更新自己;
. 具体主题(ConcreteSubject)角色:保存对具体观察者对象有用的内部状态;在这
种内部状态改变时给其观察者发出一个通知;具体主题角色又叫作具体被观察者角色;
.具体观察者(ConcreteObserver)角色:保存一个指向具体主题对象的引用;和一
个与主题的状态相符的状态。具体观察者角色实现抽象观察者角色所要求的更新自己的接口,
以便使本身的状态与主题的状态自恰。
示例代码:
1.抽象主题角色类
package com.observe; public interface AbstractWatched { //增加一个观察者 public void addAbstactWatcher(AbstractWatcher watcher); //移除一个观察者 public void removeAbstactWatcher(AbstractWatcher watcher); //移除所有的观察着 public void removeAll(); //通知所有的观察者 public void notifyWatchers(); }
2.抽象观察者角色
package com.observe; public interface AbstractWatcher { public void update(); }
3.具体主题角色(Watched)
package com.observe; import java.util.ArrayList; import java.util.List; public class ConcreteWatched implements AbstractWatched { //list:存放观察者的一个集合对象 List<AbstractWatcher> list = new ArrayList<AbstractWatcher>(); //增加一个观察者 public void addAbstactWatcher(AbstractWatcher watcher) { list.add(watcher); } //移除一个观察者 public void removeAbstactWatcher(AbstractWatcher watcher) { list.remove(watcher); } //移除所有的观察着 public void removeAll() { list.clear(); } //通知所有的观察者 public void notifyWatchers() { for(AbstractWatcher watcher : list){ watcher.update(); } } }
4.具体观察者角色(Watcher)
package com.observe; public class ConcreteWatcher implements AbstractWatcher { //观察到被观察者发生变化时,执行的方法 public void update() { System.out.println("update....."); } }
5.客户端调用:
package com.observe; public class ClientTest { public static void main(String[] args){ //定义一个被观察者对象 AbstractWatched watched = new ConcreteWatched(); //定义三个观察者对象 AbstractWatcher watcher1 = new ConcreteWatcher(); AbstractWatcher watcher2 = new ConcreteWatcher(); AbstractWatcher watcher3 = new ConcreteWatcher(); //被观察者添加观察者. 被观察者和观察者之间关系是一对多关系 watched.addAbstactWatcher(watcher1); watched.addAbstactWatcher(watcher2); watched.addAbstactWatcher(watcher3); System.out.println("第1次..."); //被观察者发生改变时,通知观察者执行相应方法 watched.notifyWatchers(); //移除一个观察者 watched.removeAbstactWatcher(watcher2); System.out.println("第2次..."); //被观察者发生改变时,通知观察者执行相应方法 watched.notifyWatchers(); //移除一个所有观察者 watched.removeAll(); System.out.println("第3次..."); //被观察者发生改变时,通知观察者执行相应方法 watched.notifyWatchers(); } }
执行结果为:
第1次... update..... update..... update..... 第2次... update..... update..... 第3次...
推模型和拉模型
在观察者模式的实现里面,又分为推模型和拉模型两种方式。
推模型
目标对象主动向观察者推送目标的详细信息,不管观察者是否需要,推送的信息通常是目
标对象的全部或部分数据,相当于是在广播通信。实现方法就是,update 方法加一个参
数,通过这个参数把数据传过去。
拉模型
目标对象在通知观察者的时候,只传递少量信息,如果观察者需要更具体的信息,由观察
者主动到目标对象中获取,相当于是观察者从目标对象中拉数据。
一般这种模型的实现中,会把目标对象自身通过update方法传递给观察者,这样在观察者
需要获取数据的时候,就可以通过这个引用来获取了。
观察者模式的优缺点
观察者模式实现了观察者和目标之间的抽象耦合
原本目标对象在状态发生改变的时候,需要直接调用所有的观察者对象,但是抽象出观察者接
口过后,目标和观察者就只是在抽象层面上耦合了,也就是说目标只是知道观察者接口,并不
知道具体的观察者的类,从而实现目标类和具体的观察者类之间解耦。
观察者模式实现了动态联动
所谓联动,就是做一个操作会引起其它相关的操作。由于观察者模式对观察者注册实行管
理,那就可以在运行期间,通过动态的控制注册的观察者,来控制某个动作的联动范围,从而
实现动态联动。
观察者模式支持广播通信
由于目标发送通知给观察者是面向所有注册的观察者,所以每次目标通知的信息就要对所有注
册的观察者进行广播。当然,也可以通过在目标上添加新的功能来限制广播的范围。
在广播通信的时候要注意一个问题,就是相互广播造成死循环的问题。比如A和B两个对象
互为观察者和目标对象,A对象发生状态变化,然后A来广播信息,B对象接收到通知后,在处
理过程中,使得B对象的状态也发生了改变,然后B来广播信息,然后A对象接到通知后,又触
发广播信息……,如此A引起B变化,B又引起A变化,从而一直相互广播信息,就造成死循环
了。
观察者模式可能会引起无谓的操作,降低性能
由于观察者模式每次都是广播通信,不管观察者需不需要,每个观察者都会被调用update方
法,如果观察者不需要执行相应处理,那么这次操作就浪费了。
增加了复杂度,容易引起误操作。死循环等。
发表评论
-
模板方法模式
2013-06-27 10:28 396引用http://eneasy.iteye.com/blog/ ... -
状态模式
2013-06-26 16:38 516引用http://blog.csdn.net/hguisu/a ... -
策略模式
2013-06-24 18:28 538定义 策略模式(Strategy)属于对象行为型设计模式,主要 ... -
代理模式-动态代理
2013-06-20 16:37 473转自:http://www.cnblogs.com/jqyp/ ... -
观察者模式-JDK支持
2013-06-18 14:39 382JDK对观察者模式的支持主要是通过Observable类和Ob ... -
备忘录模式
2013-06-14 15:45 361转载:http://blog.csdn.net/m136663 ... -
java 中介者模式
2013-06-07 16:19 568定义:用一个中介者对象封装一系列的对象交互,中介者使各对象不需 ... -
迭代器模式
2013-06-07 11:18 625定义:提供一种方法访 ... -
命令模式
2013-06-05 16:56 728定义 将一个请求封装为 ... -
责任链模式
2013-06-03 16:46 529转自:《深入浅出设计 ... -
代理模式
2013-05-27 11:07 406一、简介 代理模式有两 ... -
享元模式
2013-05-23 16:43 499一、引子 让我们先来复习下 java 中String 类型的特 ... -
门面模式
2013-05-21 15:28 401转自http://www.cnblogs.com/java-m ... -
装饰模式
2013-05-21 11:03 317动态地给一个对象添加一些额外的职责。就增加功能来说,Decor ... -
组合模式
2013-05-20 16:21 675一、引子 在大学的数据 ... -
桥接模式
2013-05-10 11:05 574认识桥接模式 (1)什么是桥接 在桥接模式里面 ... -
适配器模式
2013-05-08 14:04 6001. 概述 将一个类的接口转换成客户希望的另外一个接口 ... -
原型模式
2013-04-22 14:53 611转自:http://blog.csdn.net/zhengzh ... -
单态模式
2013-04-22 14:24 570保证一个类仅有一个实例,*提供一个访问它的全局访*点。 适 ... -
建造者模式
2013-04-18 10:27 612转自:http://www.2cto.com/kf/20120 ...
相关推荐
Qt设计模式之观察者模式
采用Java语言编写的一个观察者模式实例。观察者模式(有时又被称为模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,...
java观察者模式观察者模式java观察者模式观察者模式java观察者模式观察者模式
观察者模式及实例,适合初学者阅读 。。。。。。。。。。。。。。。
观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件...
Java 观察者模式的浅析 简单地说,观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监察一个主题对象。这样一个主题对象在状态上的变化能够通知所有的依赖于此对象的那些观察者对象,使这些观察者...
观察者模式
java 设计模式 观察者模式 简单实例 包括测试test类
观察者模式:对象之间多对一依赖的一种设计方案,被依赖的对象为Subject,依赖的对象为Observer,Subject通知Observer变化,这个例子是java内置观察者模式
设计模式之观察者模式Java版本实现和UML类设计图
设计模式-观察者模式(讲解及其实现代码)
设计模式--观察者模式java例子
运用观察者模式及MVC模式的整合,是javaWeb的简单的实现了选民投票
观察者模式Demo,设计模式,观察者模式
观察者模式使用
iOS 设计模式 观察者模式
我们开始发送消息第三步,在组件三中接收消息 第一步,我们先在main.js中注册一下bus 第二步,我们开始发送消息 第三步,在组件三中接收消息 vue的机制 观察者模式存在的意义 观察者模式 首先,提到观察者...
观察者模式小型框架