Java常见设计模式之观察者模式
在阎宏博士的《JAVA与模式》一书中开头是这样描述观察者(Observer)模式的:
观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
观察者模式的结构
一个软件系统里面包含了各种对象,就像一片欣欣向荣的森林充满了各种生物一样。在一片森林中,各种生物彼此依赖和约束,形成一个个生物链。一种生物的状态变化会造成其他一些生物的相应行动,每一个生物都处于别的生物的互动之中。
同样,一个软件系统常常要求在某一个对象的状态发生变化的时候,某些其他的对象做出相应的改变。做到这一点的设计方案有很多,但是为了使系统能够易于复用,应该选择低耦合度的设计方案。减少对象之间的耦合有利于系统的复用,但是同时设计师需要使这些低耦合度的对象之间能够维持行动的协调一致,保证高度的协作。观察者模式是满足这一要求的各种设计方案中最重要的一种。
下面以一个简单的示意性实现为例,讨论观察者模式的结构。
aaarticlea/png;base64,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YgsrdrVusXQ9bCurtbywCxZLdyyWPgTFdQ56nQlSGr3jJE3TrBGGauUmSGxhxa5WTyKBGCUsRJNQNyQDQ0SfflJmsXQWSxcorjORpzHxO9u2DUOTBjfqdxdvmJWbILGFFbvaM/3hWAgci6UTt8I6VyzYOOUafMy/6K/mPU1ObFwPKzdBYgsrdvVAuYUdi6WbwpBdkUHYg2QNrNjVY4krMQTtyjofP358IvP48ccf926CGT5+/Li3ac+C4koOCu2KPAivr6+fPn3697//vXdDyJJQXMlBoV2RR+Dr168vLy9vb2+fPn36z3/+s3dzyGJQXMlBoV2RR+Cnn37Cgr3//ve/nz59ent727tFZBkorkdEakE/8oJX2hU5PX/88ccvv/wi//7666+//fbbju0hC7KkuOqSUstG/I8lfEACxeljURpd73bwauR6kev86lfrMfbjr12gl+JKzs23b99eXl6+ffsmW97e3p6fn//666/9GkUWY0lxbZpGCigu6HJ1XRcufke6CedcURQTJeFQfsd9rwQ3VZXaGJ3UyV2yme/XnOEfX1g8haSG4krOzS+//PLHH394G798+fL58+c9mkMWZjFxxTr9qqqQd+l9FTbmFx/WzuiEb+flRESWhiMn7w3lajAx8kGguBLyPuq6/umnnwbf+vnnn//888+N20MWZzFxTdM0iqJYAXcHfhjKgOujBnV0rFh6KNVzBBI5F/Uh8HHl2MEa5qGShY0X53KOSIf125umGUxnMTjQitSPVz8FZ5ufBnmQmT++7ElxJeQdvL29vby8fP36dfDdb9++PT8///333xu3iizLksPCuo4pXiDNL8RMlxBHFTloyXSx9L7vvbJ0g3v2fS+Zh1EtoO/7sGYq/s3zHIdXVSXygNp2yGOsk5hD77VO40vBQUeKYDejWLrMpKLxkEzk5JPPGnxi8AqtT1AUxdX060gwi2eFqqpEtvHaG3UY/PHxUzRNo7/yGlBcyVl5fX19fX2d2OH333/nslfrrCuuTlWwEbfMcyini6WDMOV6uCdEC+eHYHviKg2AtGOjCCHUAhvlhR6S1Xn24zgWWZLngLBYuhYq7YBC3aXZ01+/aZplHURJ765d0omaQt6PrwWVnishtyILW6d347JX6yw55wrXB56WiISuhyXapiVkKXGVU4lu6WqyTmmtPlYLcJIkKLajT9g0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" alt="" />
观察者模式所涉及的角色有:
● 抽象主题(Subject)角色:抽象主题角色把所有对观察者对象的引用保存在一个聚集(比如ArrayList对象)里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,抽象主题角色又叫做抽象被观察者(Observable)角色。
● 具体主题(ConcreteSubject)角色:将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者(Concrete Observable)角色。
● 抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。
● 具体观察者(ConcreteObserver)角色:存储与主题的状态自恰的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态 像协调。如果需要,具体观察者角色可以保持一个指向具体主题对象的引用。
源代码
抽象主题角色类
public abstract class Subject {
/**
* 用来保存注册的观察者对象
*/
private List<Observer> list = new ArrayList<Observer>();
/**
* 注册观察者对象
* @param observer 观察者对象
*/
public void attach(Observer observer){ list.add(observer);
System.out.println("Attached an observer");
}
/**
* 删除观察者对象
* @param observer 观察者对象
*/
public void detach(Observer observer){ list.remove(observer);
}
/**
* 通知所有注册的观察者对象
*/
public void nodifyObservers(String newState){ for(Observer observer : list){
observer.update(newState);
}
}
}
具体主题角色类
public class ConcreteSubject extends Subject{ private String state; public String getState() {
return state;
} public void change(String newState){
state = newState;
System.out.println("主题状态为:" + state);
//状态发生改变,通知各个观察者
this.nodifyObservers(state);
}
}
抽象观察者角色类
public interface Observer {
/**
* 更新接口
* @param state 更新的状态
*/
public void update(String state);
}
具体观察者角色类
public class ConcreteObserver implements Observer {
//观察者的状态
private String observerState; @Override
public void update(String state) {
/**
* 更新观察者的状态,使其与目标的状态保持一致
*/
observerState = state;
System.out.println("状态为:"+observerState);
} }
客户端类
public class Client { public static void main(String[] args) {
//创建主题对象
ConcreteSubject subject = new ConcreteSubject();
//创建观察者对象
Observer observer = new ConcreteObserver();
//将观察者对象登记到主题对象上
subject.attach(observer);
//改变主题对象的状态
subject.change("new state");
} }
运行结果如下
aaarticlea/png;base64,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" alt="" />
在运行时,这个客户端首先创建了具体主题类的实例,以及一个观察者对象。然后,它调用主题对象的attach()方法,将这个观察者对象向主题对象登记,也就是将它加入到主题对象的聚集中去。
这时,客户端调用主题的change()方法,改变了主题对象的内部状态。主题对象在状态发生变化时,调用超类的notifyObservers()方法,通知所有登记过的观察者对象。
推模型和拉模型
在观察者模式中,又分为推模型和拉模型两种方式。
● 推模型
主题对象向观察者推送主题的详细信息,不管观察者是否需要,推送的信息通常是主题对象的全部或部分数据。
● 拉模型
主题对象在通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,由观察者主动到主题对象中获取,相当于是观察者从主题对象中拉数据。一般这种模型的实现中,会把主题对象自身通过update()方法传递给观察者,这样在观察者需要获取数据的时候,就可以通过这个引用来获取了。
根据上面的描述,发现前面的例子就是典型的推模型,下面给出一个拉模型的实例。
拉模型的抽象观察者类
拉模型通常都是把主题对象当做参数传递。
public interface Observer {
/**
* 更新接口
* @param subject 传入主题对象,方面获取相应的主题对象的状态
*/
public void update(Subject subject);
}
拉模型的具体观察者类
public class ConcreteObserver implements Observer {
//观察者的状态
private String observerState; @Override
public void update(Subject subject) {
/**
* 更新观察者的状态,使其与目标的状态保持一致
*/
observerState = ((ConcreteSubject)subject).getState();
System.out.println("观察者状态为:"+observerState);
} }
拉模型的抽象主题类
拉模型的抽象主题类主要的改变是nodifyObservers()方法。在循环通知观察者的时候,也就是循环调用观察者的update()方法的时候,传入的参数不同了。
public abstract class Subject {
/**
* 用来保存注册的观察者对象
*/
private List<Observer> list = new ArrayList<Observer>();
/**
* 注册观察者对象
* @param observer 观察者对象
*/
public void attach(Observer observer){ list.add(observer);
System.out.println("Attached an observer");
}
/**
* 删除观察者对象
* @param observer 观察者对象
*/
public void detach(Observer observer){ list.remove(observer);
}
/**
* 通知所有注册的观察者对象
*/
public void nodifyObservers(){ for(Observer observer : list){
observer.update(this);
}
}
}
拉模型的具体主题类
跟推模型相比,有一点变化,就是调用通知观察者的方法的时候,不需要传入参数了。
public class ConcreteSubject extends Subject{ private String state; public String getState() {
return state;
} public void change(String newState){
state = newState;
System.out.println("主题状态为:" + state);
//状态发生改变,通知各个观察者
this.nodifyObservers();
}
}
两种模式的比较
■ 推模型是假定主题对象知道观察者需要的数据;而拉模型是主题对象不知道观察者具体需要什么数据,没有办法的情况下,干脆把自身传递给观察者,让观察者自己去按需要取值。
■ 推模型可能会使得观察者对象难以复用,因为观察者的update()方法是按需要定义的参数,可能无法兼顾没有考虑到的使用情况。这就意味着出现新情况的时候,就可能提供新的update()方法,或者是干脆重新实现观察者;而拉模型就不会造成这样的情况,因为拉模型下,update()方法的参数是主题对象本身,这基本上是主题对象能传递的最大数据集合了,基本上可以适应各种情况的需要。
JAVA提供的对观察者模式的支持
在JAVA语言的java.util库里面,提供了一个Observable类以及一个Observer接口,构成JAVA语言对观察者模式的支持。
Observer接口
这个接口只定义了一个方法,即update()方法,当被观察者对象的状态发生变化时,被观察者对象的notifyObservers()方法就会调用这一方法。
public interface Observer { void update(Observable o, Object arg);
}
Observable类
被观察者类都是java.util.Observable类的子类。java.util.Observable提供公开的方法支持观察者对象,这些方法中有两个对Observable的子类非常重要:一个是setChanged(),另一个是notifyObservers()。第一方法setChanged()被调用之后会设置一个内部标记变量,代表被观察者对象的状态发生了变化。第二个是notifyObservers(),这个方法被调用时,会调用所有登记过的观察者对象的update()方法,使这些观察者对象可以更新自己。
public class Observable {
private boolean changed = false;
private Vector obs; /** Construct an Observable with zero Observers. */ public Observable() {
obs = new Vector();
} /**
* 将一个观察者添加到观察者聚集上面
*/
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
} /**
* 将一个观察者从观察者聚集上删除
*/
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
} public void notifyObservers() {
notifyObservers(null);
} /**
* 如果本对象有变化(那时hasChanged 方法会返回true)
* 调用本方法通知所有登记的观察者,即调用它们的update()方法
* 传入this和arg作为参数
*/
public void notifyObservers(Object arg) { Object[] arrLocal; synchronized (this) { if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
} for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
} /**
* 将观察者聚集清空
*/
public synchronized void deleteObservers() {
obs.removeAllElements();
} /**
* 将“已变化”设置为true
*/
protected synchronized void setChanged() {
changed = true;
} /**
* 将“已变化”重置为false
*/
protected synchronized void clearChanged() {
changed = false;
} /**
* 检测本对象是否已变化
*/
public synchronized boolean hasChanged() {
return changed;
} /**
* Returns the number of observers of this <tt>Observable</tt> object.
*
* @return the number of observers of this object.
*/
public synchronized int countObservers() {
return obs.size();
}
}
这个类代表一个被观察者对象,有时称之为主题对象。一个被观察者对象可以有数个观察者对象,每个观察者对象都是实现Observer接口的对象。在被观察者发生变化时,会调用Observable的notifyObservers()方法,此方法调用所有的具体观察者的update()方法,从而使所有的观察者都被通知更新自己。
怎样使用JAVA对观察者模式的支持
这里给出一个非常简单的例子,说明怎样使用JAVA所提供的对观察者模式的支持。在这个例子中,被观察对象叫做Watched;而观察者对象叫做Watcher。Watched对象继承自java.util.Observable类;而Watcher对象实现了java.util.Observer接口。另外有一个Test类扮演客户端角色。
源代码
被观察者Watched类源代码
public class Watched extends Observable{ private String data = ""; public String getData() {
return data;
} public void setData(String data) { if(!this.data.equals(data)){
this.data = data;
setChanged();
}
notifyObservers();
} }
观察者类源代码
public class Watcher implements Observer{ public Watcher(Observable o){
o.addObserver(this);
} @Override
public void update(Observable o, Object arg) { System.out.println("状态发生改变:" + ((Watched)o).getData());
} }
测试类源代码
public class Test { public static void main(String[] args) { //创建被观察者对象
Watched watched = new Watched();
//创建观察者对象,并将被观察者对象登记
Observer watcher = new Watcher(watched);
//给被观察者状态赋值
watched.setData("start");
watched.setData("run");
watched.setData("stop"); } }
Test对象首先创建了Watched和Watcher对象。在创建Watcher对象时,将Watched对象作为参数传入;然后Test对象调用Watched对象的setData()方法,触发Watched对象的内部状态变化;Watched对象进而通知实现登记过的Watcher对象,也就是调用它的update()方法。
原文地址:http://www.cnblogs.com/java-my-life/archive/2012/05/16/2502279.html
Java常见设计模式之观察者模式的更多相关文章
- JAVA的设计模式之观察者模式----结合ActiveMQ消息队列说明
1----------------------观察者模式------------------------------ 观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的 ...
- JAVA基础——设计模式之观察者模式
观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.模型-视图(Model/View)模式.源-监听器(Source/Listener)模式或从属者(Dependen ...
- Java常见设计模式学习(非原创)
文章大纲 一.策略模式二.观察者模式三.工厂模式四.单例模式五.其他模式六.设计模式总结七.参考文章 一.策略模式 现在假设我们有个"鸭子项目",首先我们用OOP(面向对象)的 ...
- java小白设计模式之观察者模式
观察者模式: 对象之间多对一依赖的一种设计方案,被依赖对象为Subject(一),依赖对象为Observer(多),Subject通知Observer变化直接代码: package com.wz.tw ...
- Java常见设计模式之代理模式
指由一个代理主题来操作真实主题,真实主题执行具体的业务操作,而代理主题负责其它相关业务的处理.比如生活中的通过代理访问网络,客户通过网络代理连接网络(具体业务),由代理服务器完成用户权限和访问限制等与 ...
- Java常见设计模式之工厂模式
工厂模式在我们日常的应用中应当算是比较广泛的一种设计模式了.今天让我们一起来学习一下,工厂的设计模式. 工厂模式在<Java与模式>中分为三类: 1)简单工厂模式(Simple F ...
- Java常见设计模式之单例模式
1.何为单例模式? 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的 ...
- java常见设计模式简要总结
设计模式六大原则 1.开放封闭原则:对扩展开放,对修改封闭,意即程序拓展时不要动原有的代码 2.LSP原则:任何基类可以出现的地方,子类一定可以出现 3.依赖倒置原则:使用接口,依赖于抽象而不是具体 ...
- Java常见设计模式之适配器模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述适配器(Adapter)模式的: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能 ...
随机推荐
- 【译】快速高效学习Java编程在线资源Top 20
想要加强你的编程能力吗?想要提升你的 Java 编程技巧和效率吗? 不用担心.本文将会提供快速高效学习 Java 编程的 50 多个网站资源: 开始探索吧: 1.MKyong:许多开发者在这里可以找到 ...
- PHP安全编程之php.ini配置
1.register_globals=On <?php//ex1.php if(check_admin()) { $is_admin=true; } if($is_admin) { ...
- R语言数据管理(四):数据导出
与read.*函数对应,导出函数为write.*函数. 比较常见的为write.csv和write.table. 一般格式: setwd("D:\\") write.table(y ...
- python发布包流程
1.新建文件夹suba和subb,文件夹下新建__init__.py,内容可以为空 2.suba内新建文件aa.py bb.py 3.subb内新建文件cc.py dd.py 4.setup.py文件 ...
- 小程序真机GET请求出现406错误
问题:微信开发模拟器请求成功,获得数据,但是在真机上出现406请求错误,无法获得请求结果 原因:真机微信小程序的请求头与模拟器不同 怎么发现的:在请求头强制添加Accept即可解决 修复:在请求Hea ...
- 算法(Algorithms)第4版 练习 2.2.11(3)
关键代码实现: public static void sort(Comparable[] input) { int N = input.length; aux = input.clone();//mu ...
- window.onload 添加多个函数绑定
window.onload = function(){alert(2)} function addEvent (fun) { var old = window.onload; if(typeof ol ...
- python3反射解析
python反射解析 一. 简介 python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数分别用于对对象内部执行:检查是否含有某 ...
- 动态规划 最长回文子串 leetcode5
public static String longestPalindrome(String s) { if(null==s||s.length()==0) return s; int n=s.leng ...
- 05 - Django应用第二步
知识点 1) 数据库的配置 涉及到INSTALL_APPS的配置等 初次创建数据的命令 2) 模型的编写 模型的创建方式, 写一个类继承自models.Model 模型的数据类型 外键 自动创建ID列 ...