在Java中通过Observable类和Observer接口实现了观察者模式。一个Observer对象监视着一个Observable对象的变化,当Observable对象发生变化时,Observer得到通知,就可以进行相应的工作。例如在文档/视图结构中,文档被修改了,视图就会得到通知。
java.util.Observable中有两个方法对Observer特别重要,一个是setChange()方法用来设置一个内部标志位注明数据发生了变化;一个是notifyObservers()方法会去调用一个列表中所有的Observer的update()方法,通知它们数据发生了变化。
Observer通过Observable的addObserver()方法把自己添加到这个列表中。这个列表虽然由Observable拥有,但Observable并不知道到底有哪些Observer正在观察等待通知。Observable只提供一个方法让Observer能把自己添加进列表,并保证会去通知Observer发生了变化。通过这种机制,可以有任意多个Observer对Observable进行观察,而不影响Observable的实现。
一个简单例子:
import java.util.Observable;
public class SimpleObservable extends Observable
{
private int data = 0;
public int getData(){
return data;
}
public void setData(int i){
if(this.data != i){ this.data = i; setChange();}
notifyObservers();
//只有在setChange()被调用后,notifyObservers()才会去调用update(),否则什么都不干。
}
}
}
import java.util.Observable;
import java.util.Observer;
public class SimpleObserver implements Observer
{
public SimpleObserver(SimpleObservable so){
so.addObserver(this );
}
public void update(Observable o,Object arg/*任意对象,用于传递参数*/){
System.out.println(“Data has changed to” + (SimpleObservable)o.getData());
}
}
public class SimpleTest
{
public static void main(String[] args){
SimpleObservable doc = new SimpleObservable ();
SimpleObserver view = new SimpleObserver (doc);
doc.setData(1);
doc.setData(2);
doc.setData(2);
doc.setData(3);
}
}
Data has changed to 1
Data has changed to 2 //第二次setData(2)时由于没有setChange,所以update没被调用
Data has changed to 3
Observable类有两个私有变量。一个boolean型的标志位,setChange()将它设为真,只有它为真时,notifyObservers方法才会调用Observer的update方法,clearChange()设标志位为假,hasChange返回当前标志位的值。另一个是一个Vector,保存着一个所有要通知的Observer列表,addObserver添加Observer到列表,deleteObserver从列表中删除指定Observer,deleteObservers清空列表,countObservers返回列表中Observer的数目,在Observer对象销毁前一定要用deleteObserver将其从列表中删除,不然因为还存在对象引用的关系,Observer对象不会被垃圾收集,造成内存泄漏,并且已死的Observer仍会被通知到,有可能造成意料外的错误,而且随着列表越来越大,notifyObservers操作也会越来越慢。
Observable的所有方法都是同步的,保证了在一个线程对其标志位、列表进行操作时,不会有其它线程也在操作它。
Observable的notifyObservers(Object obj)形式可以再调用update时将参数传进去。
通知顺序通常时越晚加入列表的越先通知。update会被依次调用,由于一个update返回后下一个update才被调用,这样当update中有大量操作时,最好将其中的工作拿到另一个线程或者Observer本身同时也是一个Thread类,Observer先挂起,在update中被唤醒,这样会有一个隐患,Observer线程还没来得及挂起,update就被调用了,通知消息就这样被错过了,一种解决办法是在Observer中实现一个同步的队列结构,并有一个类来封装参数,update实现一个参数类的对象把接收到的通知消息的参数封装在里面,然后把其加进队列,run方法从队列中移除参数对象,并进行处理,这保证了没有通知信息被丢失。
在多线程时,只有Observer会与单线程不同,Observable不需任何改变来支持多线程,因为它又很多作为单独线程运作的Observer。
一个多线程例子:
import java.util.*;
public class SimpleObserverEx extends Thread implements Observer
{
Queue queue;//利用一个消息队列来接收Observable的通知,保证消息不会丢失
public void run(){
while(true){
ArgPack a = (ArgPack) queue.dequeue();
Observable o = a.o;
Object obj = a.arg;
//…执行相应的工作
}
}
public void update(Observable o, Object arg){
ArgPack a = new ArgPack (o,arg);
queue.queue(a);
}
}
import java.util.*;
public class Queue extends LinkedList{
public synchronized void queue(Object o){
addLast(o);
notify();
}
public synchronized void dequeue(){
while(this.isEmpty()){
try{
wait();
}
catch(InterruptedException el){
}
}
Object o;
try{
o =this.removeFirst();
}
catch(NoSuchElementException){
o = null;
}
return o;
}
}
public class ArgPack
{
public Observable o;
public Object obj;
public ArgPack (Observable o,Object obj){
this.o = o;this.obj = obj;
}
}
Observable是一个类而不是一个接口这限制了它的使用,一个解决的办法是在一个Observable类中把我们的类包装进去(把我们的类实例当作Observable的域),因为Observable中的setChange是一个protected方法,我们没法在外面调用它。所以没法在我们的类中包装一个Observable,但是如果我们的类中同样也有protected方法,那这个办法就无法使用
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhouyongyang621/archive/2010/07/20/5750702.aspx
分享到:
相关推荐
Observer观察者模式是一种行为设计模式,它允许你定义一个订阅机制,可以在对象状态改变时通知多个“观察”该对象的其他对象。这个模式的核心概念是发布-订阅,即发布者(被观察对象)向订阅者(观察者)广播事件或...
**C#面向对象设计模式纵横谈(19)**:**观察者模式**(Observer Pattern)是行为型模式的一种,它在软件工程中扮演着至关重要的角色。观察者模式是一种设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态...
### (行为型模式) Observer 观察者模式 #### 概述 观察者模式是一种行为设计模式,它定义了一种一对多的关系,让多个观察对象同时监听某一个主题对象。当主题对象发生变化时,所有观察者对象都会收到通知并进行...
观察者模式(Observer Pattern)是一种行为设计模式,它允许你定义一个订阅机制,可以在对象状态改变时通知多个“观察”该对象的其他对象。在软件工程中,这常用于实现事件驱动编程,使得系统能够及时响应变化。 在...
2.Observer(观察者) 为那些在目标发生改变时需获得通知的对象定义一个更新接口。 3.ConcreteSubject(具体目标) 将有关状态存入各ConcreteObserver对象。 当它的状态发生改变时,向它的各个观察者发出通知。...
本篇文章将深入探讨“Observer”观察者模式,这是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 观察者模式的核心概念是主题...
在观察者模式中,通常有两个主要角色:主题(Subject)和观察者(Observer)。主题是被观察的对象,它持有一个观察者列表,并负责通知这些观察者状态的变化。观察者是依赖主题的对象,当接收到主题的通知时,它们会...
这个模式的核心概念是一个主题(Subject)对象和一个或多个观察者(Observer)对象之间的关系,主题可以被多个观察者监视,当主题的状态发生改变时,会自动通知所有观察者。 在Java中,`java.beans....
观察者模式(Observer)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。这种模式在C++中广泛应用,特别是在需要...
本文实例讲述了C#设计模式之Observer观察者模式解决牛顿童鞋成绩问题。分享给大家供大家参考,具体如下: 一.理论定义 观察者模式 描述了 一种 一对多的关系。 当某一对象的状态发生改变时,其他对象会得到 改变的...
观察者模式(Observer Pattern)是设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。这种模式常用于实现事件驱动的系统或者...
观察者模式详解 观察者模式是23种设计模式中的一种,尤其是在软件设计过程中体现的更是立足无穷。本文将详细讲解观察者模式的概念和实现,通过代码注释来解释各个组件的作用。 一、观察者模式的定义 观察者模式是...
观察者(Observer)模式是一种行为设计模式,它允许你定义一个订阅机制,可以在对象状态改变时通知多个“观察”该对象的其他对象。在Java编程语言中,这种模式被内置在`java.util.Observable`和`java.util.Observer`类...
观察者模式(Observer)是设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。这种模式在软件开发中广泛应用于事件处理和实时...
- `addObserver(Observer o)`:添加一个新的观察者到观察者列表。 - `deleteObserver(Observer o)`:移除指定的观察者。 - `notifyObservers()`或`notifyObservers(Object arg)`:当被观察对象的状态改变时,调用...