您的位置:首页 > 编程语言 > Java开发

Java观察者模式 java.util.Observa…

2014-12-16 20:45 405 查看



Java观察者模式 java.util.Observable 与 java.util.Observer
的理解

JDK1.2后,Java提供了对观察者模式的支持接口和实现类。

其中接口 java.util.Observer 用来指定观察者,观察者必须实现 void update(Observable o,
Object arg) 方法。

而 java.util.Observable
用来指定观察物(被观察者、可被观察的),并且提供了一系列的方法。读者可以很轻易的使用这个接口和实现类来实现观察者模式。

Part II

java.util.Observer 只有一个简单的方法 void update(Observable o, Object
arg)

其中,参数 Observable o 用于指定触发 update 方法的对象, Object arg 用于指定触发 update
方法时候的附加参数。

如果有桌面应用开发的读者应该很了解,这跟事件处理机制是完全一样的,其中 Observable o 可被看作事件源。 Object
arg 可被看作消息。

Part III

说了那么多,我们还是动手写个例子吧。这里我们以读者订阅杂志为例子。

package com.gzmu.observer.observable;

import java.util.Observable;

public class Publisher extends Observable {

private String magazineName;

public String getMagazineName() {

return magazineName;

}

public void publish(String magazineName) {

this.magazineName = magazineName;

setChanged();

notifyObservers(this);

}

}


package com.gzmu.observer.observer;

import java.util.Observable;

import java.util.Observer;

import com.gzmu.observer.observable.Publisher;

public class Reader implements Observer {

@Override

public void update(Observable o, Object arg) {

Publisher p = (Publisher) o;

System.out.println("我要订阅" + p.getMagazineName());

}

}


package com.gzmu.observer.test;

import org.junit.Test;

import com.gzmu.observer.observable.Publisher;

public class TestCase {

@Test

public void register() {

Publisher publisher = new Publisher();

publisher.publish("Kent.Kuan的技术空间");

}

}


这里很清楚的看到,当出版社出版杂志的时候,会主动的告知读者,读者就会订阅杂志,这也是一种主动推送的模式。

Part IV

这里大家会发现,调用 notifyObservers() 的时候,为什么传进当前对象 this 呢?而这个 this,
我们在读者那也没用到啊。这个问题曾经也让我觉得很苦恼,之前我也不清楚为什么观察者要拿到被观察对象的引用,但是,我们看看下面这个例子。

首先我们引用一个新的类:

package com.gzmu.observer.observable;

import java.util.Observable;

public class TVStation extends Observable {

private String programmeName;

public void play(String programmeName) {

this.programmeName = programmeName;

setChanged();

notifyObservers(this);

}

public String getProgrammeName() {

return programmeName;

}

}


然后修改Reader和TestCase:

package com.gzmu.observer.observer;

import java.util.Observable;

import java.util.Observer;

import com.gzmu.observer.observable.Publisher;

import com.gzmu.observer.observable.TVStation;

public class Reader implements Observer {

@Override

public void update(Observable o, Object arg) {

if (o instanceof Publisher) {

Publisher p = (Publisher) o;

System.out.println("我要订阅" + p.getMagazineName());

}

if (o instanceof TVStation) {

TVStation t = (TVStation) o;

System.out.println("我要收看" + t.getProgrammeName());

}

}

}


package com.gzmu.observer.test;

import org.junit.Test;

import com.gzmu.observer.observable.Publisher;

import com.gzmu.observer.observable.TVStation;

import com.gzmu.observer.observer.Reader;

public class TestCase {

@Test

public void register() {

Reader reader = new Reader();

Publisher publisher = new Publisher();

publisher.addObserver(reader);

TVStation tvStation = new TVStation();

tvStation.addObserver(reader);

publisher.publish("Kent.Kwan的技术空间");

tvStation.play("色戒");

}

}


最后我们可以看到,同一个观察者其实是可以注册到不同的被观察者上面的,而传过来的 Oberverable o
其实可以用来检验到底是谁发过来的消息。

除此以外,我们还可以在接受到消息之后,进行撤销观察的工作。

package com.gzmu.observer.observer;

import java.util.Observable;

import java.util.Observer;

import com.gzmu.observer.observable.Publisher;

import com.gzmu.observer.observable.TVStation;

public class Reader implements Observer {

@Override

public void update(Observable o, Object arg) {

if (o instanceof Publisher) {

Publisher p = (Publisher) o;

p.deleteObserver(this);

System.out.println("我要订阅" + p.getMagazineName());

}

if (o instanceof TVStation) {

TVStation t = (TVStation) o;

System.out.println("我要收看" + t.getProgrammeName());

}

}

}


通过 deleteObserver() 方法就可以撤销观察出版社对象。

转:http://xpws2006.blog.163.com/blog/static/95438577201102432840729/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: