文档章节

观察者模式(Observer Pattern)

蜀山下的鱼
 蜀山下的鱼
发布于 2015/04/29 00:39
字数 1567
阅读 11
收藏 0

 

观察者模式:顾名思义,就是观察一些人或一些事干了什么,引发了观察者的反应。

 

java自己定义了Observable类(被观察者)和Observer接口(观察者):

 

java.util.Observable  :表示应用程序想要观察的对象。

                                              一个 observable 对象可以有一个或多个观察者。

                                     观察者可以是实现了 Observer 接口的任意对象。

                                     一个 observable 实例改变后,调用ObservablenotifyObservers 方法的应用程序会通过调用观察者的

                                      update 方法来通知观察者该实例发生了改变。

                                     新创建一个 observable 对象时,其观察者集是空的。当且仅当equals 方法为两个观察者返回 true 时,才认为

                                     它们是相同的。

方法摘要

 void addObserver(Observer o)
          如果观察者与集合中已有的观察者不同,则向对象的观察者集中添加此观察者。
protected  void clearChanged()
          指示对象不再改变,或者它已对其所有的观察者通知了最近的改变,所以 hasChanged 方法将返回 false。
 int countObservers()
          返回 Observable 对象的观察者数目。
 void deleteObserver(Observer o)
          从对象的观察者集合中删除某个观察者。
 void deleteObservers()
          清除观察者列表,使此对象不再有任何观察者。
 boolean hasChanged()
          测试对象是否改变。
 void notifyObservers()
          如果 hasChanged 方法指示对象已改变,则通知其所有观察者,并调用 clearChanged 方法来指示此对象不再改变。
 void notifyObservers(Object arg)
          如果 hasChanged 方法指示对象已改变,则通知其所有观察者,并调用 clearChanged 方法来指示此对象不再改变。
protected  void setChanged()
          标记此 Observable 对象为已改变的对象;现在 hasChanged 方法将返回 true。

 

 

接口 Observer:一个可在观察者要得到 observable 对象更改通知时可实现Observer 接口的类。

 

方法摘要
 void update(Observable o,Object arg)
          只要改变了 observable 对象就调用此方法。

 

 

假设这样一个场景:    农村留守家庭里有爷爷奶奶,两个上初中的外孙,哥哥和弟弟。但是哥哥不好好上学,整天跑去上网,奶奶很担心,就叫弟弟时常监督(观察)哥哥的动向,要是发现哥哥去上网了,就回来报告。

 

 

Brother 类:被观察者

package com.mayi.file;

import java.util.Observable;
/**
 * 
 * @author Administrator
 * 哥哥经常跑去上网,奶奶派了弟弟去监督他
 *
 */
public class Brother extends Observable {
	private final Integer flag =1;

	public Brother() {
		super();
	}	
	//哥哥跑去上网,就通知奶奶;
	public void G0_Internet(){
		setChanged();//必须调用
		System.out.println("------>发现哥哥要去网吧了!");
		//设置参数,做更多的逻辑处理
		this.notifyObservers(flag);
		//this.notifyObservers();
	}
}


LittleBrother类:观察者

package com.mayi.file;

import java.util.Observable;
import java.util.Observer;
/**
 * 
 * @author Administrator
 *弟弟受奶奶指派,监督哥哥的行为,当他发现哥哥去上网的时候就去通知奶奶。
 */
public class LittleBorther implements Observer {

	public LittleBorther() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void update(Observable arg0, Object arg1) {
		//可以根据arg1的参数分别处理不同的逻辑事件
		System.out.println("接收到得参数arg1是:"+arg1);
		System.out.println("弟弟:奶奶,哥哥跑去上网了");
	}
}


Test类:

package com.mayi.test;
import com.mayi.file.*;
public class Test {

	public static void main(String[] args) {
		Brother brother = new Brother();
		
		brother.addObserver(new LittleBorther());//添加觀察者
		
		brother.G0_Internet();//哥哥去上網
	}

}


输出:

------>发现哥哥要去网吧了!
接收到得参数arg1是:1
弟弟:奶奶,哥哥跑去上网了


 

 

优点

  • 支持松耦合和减少依赖性。客户端不再依赖于观察器,因为通过使用主体和 Observer 接口对客户端进行了隔离。许多框架具有此优点,在这些框架中的应用程序组件可以注册为当(低级)框架事件发生时得到通知。结果,框架将调用应用程序组件,但不会依赖于它。
  • 观察器数目可变。观察器可以在运行时附加和分离,因为主体对于观察器数目没有任何假定。此功能在这样的情况下是很有用的:观察器数在设计时是未知的。例如,如果用户在应用程序中打开的每个窗口都需要一个观察器。

缺点

  • 性能降低。在许多实现中,观察器的 update() 方法可能与主体在同一线程中执行。如果观察器列表很长,则执行 Notify() 方法可能需要很长时间。抽取对象依赖性并不意味着添加观察器对应用程序没有任何影响。
  • 内存泄漏。在 Observer 中使用的回调机制(当对象注册为以后调用时)会产生一个常见的错误,从而导致内存泄漏,甚至是在托管的 C# 代码中。假定观察器超出作用范围,但忘记取消对主体的订阅,那么主体仍然保留对观察器的引用。此引用防止垃圾收集在主体对象也被破坏之前重新分配与观察器关联的内存。如果观察器的生存期比主体的生存期短得多(通常是这种情况),则会导致严重的内存泄漏。
  • 隐藏的依赖项。观察器的使用将显式依赖性(通过方法调用)转变为隐式依赖性(通过观察器)。如果在整个应用程序中广泛地使用观察器,则开发人员几乎不可能通过查看源代码来了解所发生的事情。这样,就使得了解代码更改的含意非常困难。此问题随传播级别急剧增大(例如,充当 Subject 的观察器)。因此,应该仅在少数定义良好的交互(如 Model-View-Controller 模式中模型和视图之间的交互)中使用观察器。最好不要在域对象之间使用观察器。
  • 测试 / 调试困难。尽管松耦合是一项重大的体系结构功能,但是它可以使开发更困难。将两个对象去耦的情况越多,在查看源代码或类的关系图时了解它们之间的依赖性就越难因此,仅当可以安全地忽略两个对象之间的关联时才应该将它们松耦合(例如,如果观察器没有副作用)。

本文转载自:http://blog.csdn.net/caiwenfeng_for_23/article/details/8448701

蜀山下的鱼
粉丝 9
博文 405
码字总数 0
作品 0
广州
高级程序员
私信 提问
设计模式(Swift) - 3.观察者模式、建造者模式

上一篇 设计模式(Swift) - 2.单例模式、备忘录模式和策略模式中讲了三种常见的设计模式. 单例模式: 限制了类的实例化,一个类只能实例化一个对象,所有对单例对象的引用都是指向了同一个对象....

Dariel
2018/07/01
0
0
Java设计模式系列一(前言)

说起设计模式,很多人都会觉得这个概念很熟悉,会想到单例模式、工厂模式等等,但是似乎又说不出来什么,说不上它的核心思想和设计原则。其实我们的项目中,为了代码复用,增加可维护性,很多...

Mooree
04/07
0
0
javascript 观察者模式和发布订阅模式

通过例子理解观察者模式和发布订阅模式的区别 观察者模式 Subject 是一个主题,Observer 是一个观察者。观察者可以订阅主题,主题发生变化会通知观察者。这是一个典型的观察者模式 12345678...

大灰狼的小绵羊哥哥
03/05
0
0
设计模式——Java中常用的9种设计模式

Factory Pattern(工厂模式)   将程序中创建对象的操作,单独出来处理,大大提高了系统扩展的柔性,接口的抽象化处理给相互依赖的对象创建提供了最好的抽象模式。 2. Facade Pattern (门面...

utopia1985
2013/06/19
0
0
折腾Java设计模式之观察者模式

观察者模式 Define a one-to-many dependency between objects where a state change in one object results in all its dependents being notified and updated automatically. 直译过来就是......

大萌小路
04/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Java的战争

本文来自微信公众号: 金捷幡(ID:jin-jiefan) ,作者:金捷幡,封面:拉里·埃里森(东方IC) 2019年5月,彻底撕破脸的特朗普掀起对华为的战争,谷歌被迫吊销了华为的Android授权。开源软...

Java领航员
38分钟前
1
0
超详细的LM3414MRX/NOPB规格参数介绍就在这里

超详细的LM3414MRX/NOPB规格参数介绍就在这里 描述 LM3414和LM3414MRX/NOPB是具有1-A 60 W(1)共阳极功能的恒流降压LED驱动器。它们适用于驱动单串3-W HBLED,效率高达96%。它们可接受4.5...

不能吃肉的仙女
44分钟前
1
0
Eclipse国内镜像源配置方法

Table of Contents 我们在国内从官网下载Eclipse以及插件非常慢,那么,有没有方法变快呢? 有,那就是使用国内的公开镜像源替换官方源。 1 下载Eclipse 首先,我们看一个链接地址: http:/...

求神
今天
5
0
java 请求服务

一.第一种基于java web http 请求服务,必须用tomcat 容器启动才能对外提供服务 在maven 工程中pox 文件导入jar <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>h......

zaolonglei
今天
5
0
HDFS工作机制——自开发分布式数据采集系统

需求描述: 在业务系统的服务器上,业务程序会不断生成业务日志(比如网站的页面访问日志) 业务日志是用log4j生成的,会不断地切出日志文件,需要定期(比如每小时)从业务服务器上的日志目...

须臾之余
今天
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部