转自:http://www.cnblogs.com/java-my-life/archive/2012/05/16/2502279.html

在阎宏博士的《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()方法。

《JAVA与模式》之观察者模式的更多相关文章

  1. java 代理模式,观察者模式

    代理模式1 import <a href="http://lib.csdn.net/base/17" class='replace_word' title="Jav ...

  2. 设计模式--观察者模式初探和java Observable模式

    初步认识观察者模式 观察者模式又称为发布/订阅(Publish/Subscribe)模式,因此我们可以用报纸期刊的订阅来形象的说明: 报社方负责出版报纸. 你订阅了该报社的报纸,那么只要报社发布了新报 ...

  3. 《JAVA与模式》之观察者模式(转载)

    <JAVA与模式>之观察者模式(转载)  原文链接:http://www.cnblogs.com/java-my-life/archive/2012/05/16/2502279.html ...

  4. java设计模式7.策略模式、模板方法模式、观察者模式

    策略模式 策略模式的用意,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以在不影响到客户端的情况下发生变化. 环境角色:持有一个抽象策略角色的引用. 抽象策略 ...

  5. 大型Java进阶专题(八)设计模式之适配器模式、装饰者模式和观察者模式

    前言 ​ 今天开始我们专题的第八课了.本章节将介绍:三个设计模式,适配器模式.装饰者模式和观察者模式.通过学习适配器模式,可以优雅的解决代码功能的兼容问题.另外有重构需求的人群一定需要掌握装饰者模式. ...

  6. Java设计模式之十三 ---- 观察者模式和空对象模式

    前言 在上一篇中我们学习了行为型模式的备忘录模式(Memento Pattern)和状态模式(Memento Pattern).本篇则来学习下行为型模式的最后两个模式,观察者模式(Observer P ...

  7. <代码整洁之道>、<java与模式>、<head first设计模式>读书笔记集合

    一.前言                                                                                       几个月前的看书笔记 ...

  8. Java设计模式之《观察者模式》及应用场景

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6513651.html 观察者模式,又可以称之为发布-订阅模式,观察者,顾名思义,就是一个监 ...

  9. 《java与模式》

    2012年3月 随笔档案 - java_my_life - 博客园--此网友 12年的博客都是和模式有关的,希望可以多看看.http://www.cnblogs.com/java-my-life/ar ...

随机推荐

  1. JAVA-堆区,栈区,方法区。

    转载:http://blog.csdn.net/wangxin1982314/article/details/50293241 堆区: 村线程操纵的数据(对象形式存放) 1 存储的全部是对象,每个对象 ...

  2. android JNI 调用NDK方法

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  3. Storm中遇到的日志多次重写问题(一)

    业务描述: 统计从kafka spout中读取的数据条数,以及写入redis的数据的条数,写入hdfs的数据条数,写入kafaka的数据条数.并且每过5秒将数据按照json文件的形式写入日志.其中保存 ...

  4. [问题]apparmor 问题导致mysql切换datadir目录失败

    问题: 在mysql切换datadir后,mysql服务无法启动.出现错误说plugin表无法读取,需要用mysql_upgrade创建.但是其实不是这个问题. 原因: apparmor 会限制程序对 ...

  5. SQL语句中的where 1=1 和0=1

    摘自:http://blog.sina.com.cn/s/blog_afe616ab0101camd.html SQL where 1=1 和0=1的作用 where 1=1; 这个条件始终为True ...

  6. 异常处理之“The remote certificate is invalid according to the validation praocedure.”

    参考文章:http://brainof-dave.blogspot.com.au/2008/08/remote-certificate-is-invalid-according.html 参考文章:h ...

  7. HAProxy介绍

    简单说明 HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.HAProxy特别适用于那些负载特大的web站点,这些站点通常又需 ...

  8. C#基础---Attribute(标签) 和 reflect(反射) 应用二

    以前我有写过一篇有关,打标签和反射的应用,主要用于类中字段的验证.下面是连接 C#基础---Attribute(标签) 和 reflect(反射) 应用. 这个项目迭代发现公司项目里面发现老代码对业务 ...

  9. github如何删除一个(repository)仓库

    GitHub 是一个面向开源及私有软件项目的托管平台,因为只支持 Git 作为唯一的版本库格式进行托管,故名 GitHub.作为开源代码库以及版本控制系统,Github拥有140多万开发者用户.随着越 ...

  10. 微信随机红包(Java)

    概述 最近受一朋友提醒,问微信红包怎么实现的,当时思考了一下,觉得好像很容易,可是当真正实现的时候,发现其中有不少问题,于是小白博主查阅资料,其中资料主要来源于知乎的一篇讨论<微信红包的随机算法 ...