在阎宏博士的《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常见设计模式之观察者模式的更多相关文章

  1. JAVA的设计模式之观察者模式----结合ActiveMQ消息队列说明

    1----------------------观察者模式------------------------------ 观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的 ...

  2. JAVA基础——设计模式之观察者模式

    观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.模型-视图(Model/View)模式.源-监听器(Source/Listener)模式或从属者(Dependen ...

  3. Java常见设计模式学习(非原创)

    文章大纲 一.策略模式二.观察者模式三.工厂模式四.单例模式五.其他模式六.设计模式总结七.参考文章   一.策略模式 现在假设我们有个"鸭子项目",首先我们用OOP(面向对象)的 ...

  4. java小白设计模式之观察者模式

    观察者模式: 对象之间多对一依赖的一种设计方案,被依赖对象为Subject(一),依赖对象为Observer(多),Subject通知Observer变化直接代码: package com.wz.tw ...

  5. Java常见设计模式之代理模式

    指由一个代理主题来操作真实主题,真实主题执行具体的业务操作,而代理主题负责其它相关业务的处理.比如生活中的通过代理访问网络,客户通过网络代理连接网络(具体业务),由代理服务器完成用户权限和访问限制等与 ...

  6. Java常见设计模式之工厂模式

    工厂模式在我们日常的应用中应当算是比较广泛的一种设计模式了.今天让我们一起来学习一下,工厂的设计模式. 工厂模式在<Java与模式>中分为三类:     1)简单工厂模式(Simple F ...

  7. Java常见设计模式之单例模式

         1.何为单例模式? 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的 ...

  8. java常见设计模式简要总结

    设计模式六大原则 1.开放封闭原则:对扩展开放,对修改封闭,意即程序拓展时不要动原有的代码 2.LSP原则:任何基类可以出现的地方,子类一定可以出现 3.依赖倒置原则:使用接口,依赖于抽象而不是具体 ...

  9. Java常见设计模式之适配器模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述适配器(Adapter)模式的: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能 ...

随机推荐

  1. Android笔记之使用Glide加载网络图片、下载图片

    Glide简介 不想说太多,真的很方便:P)可以节省我不少时间 GitHub地址:https://github.com/bumptech/glide 加载网络图片到ImageView Glide.wi ...

  2. activiti基础--2----------------------(流程定义)

    Deployment 部署对象 1.一次部署的多个文件信息,对于不需要的流程可以删除和修改 2.对应的表 act_re_deployment #部署对象表 act_re_procdef #流程定义表 ...

  3. linux 基础2-null,cut,wc,head,tail

    一. 特殊文件: /dev/null和/dev/tty Linux系统提供了两个对Shell编程非常有用的特殊文件,/dev/null和/dev/tty.其中/dev/null将会丢掉所有写入它的数据 ...

  4. python 的for else语句

    for中间不是break出来的,是正常循环完跳出循环的会执行else内的语句 while else语句也是如此 这个以前的常见语言没有,特此记录

  5. linux 指令(经常更新)

    添加一个服务 # sudo update-rc.d 服务名 defaults 99 删除一个服务 # sudo update-rc.d 服务名 remove 临时重启一个服务 # /etc/init. ...

  6. 用Java实现断点续传的基本思路和代码

    用Java实现断点续传的基本思路和代码   URL url = new URL(http://www.oschina.net/no-exist.zip); HttpURLConnection http ...

  7. 每天一个Linux命令(34)grep命令

          grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具 ...

  8. linux FAQ(zz)

    1.Which is the command used to find the available shells in your Operating System Linux ? Ans : $ech ...

  9. MySQL跳过密码登录

    第一种 1.1停止mysql服务 1.2以管理员身份运行cmd,执行以下命令 cd C:\Program Files\mysql-5.7.17-winx64\bin mysqld --skip-gra ...

  10. 《python基础教程(第二版)》学习笔记 基础部分(第1章)

    <python基础教程(第二版)>学习笔记 基础部分(第1章)python常用的IDE:Windows: IDLE(gui), Eclipse+PyDev; Python(command ...