Java观察者模式 java.util.Observable 与 java.util.Observer 的理解及测试实例
来源:互联网 发布:鲸藤壶 知乎 编辑:程序博客网 时间:2024/05/16 04:44
声明:本文章是转载自
Kent.Kwan.的技术专栏
http://blog.csdn.net/kenthong/article/details/5725522。文章中的总结部分是对原博文的补充,是基于其他网友的讨论和自己的理解。若有不同观点,请留言指教。Part I
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() 方法就可以撤销观察出版社对象。
自己的测试代码
主程序
package edu.wit.kelvin.demo;public class Main {public static void main(String[] args){// 创建一个观察者对象Reader r = new Reader() ;// 创建一个被观察者对象Publicher p = new Publicher() ;// 指定r为p的观察者,建立观察者和被观察者之间的关联p.addObserver(r) ;p.publich("War and Peace!") ;}}
观察者类package edu.wit.kelvin.demo; import java.util.Observer;import java.util.Observable;import edu.wit.kelvin.demo.Publicher;public class Reader implements Observer{public void update(Observable o , Object args){Publicher p = (Publicher)o ;System.out.println("i will subscribe "+p.getMagazineName()) ;System.out.println("i will subscribe "+args) ;System.out.println("i will subscribe "+o) ;}}
被观察者类package edu.wit.kelvin.demo;import java.util.Observable;public class Publicher extends Observable{private String magazineName ;public String getMagazineName(){return this.magazineName;}public void publich(String magazineName){this.magazineName = magazineName ;setChanged() ;this.notifyObservers(this) ;}}
运行结果
i will subscribe War and Peace!i will subscribe edu.wit.kelvin.demo.Publicher@1bab50ai will subscribe edu.wit.kelvin.demo.Publicher@1bab50a
由此可见当在被观察者类中,notifyObservers(this)时,update的第二个参数为被观察者this。与第一个参数一样。由此可以证明,notifyObservers(args)中的参数是传递给了update()的第二个参数的。
总结:
- 消息在被观察者和观察者之间的传递流程
- 被观察者调用setChanged()方法,相当于发出一个信号,告诉系统,自己的状态发生了改变,告诉系统区通知观察者。
- 被观察者,接着调用notifyObservers(args);通知观察者,args为要传递给观察者的参数,即观察者update()中的第二个参数(object args)
- 执行观察者的update()方法
2. 注意
notifyObservers(args)中的args传递给了update(Observable o , Object args)的args,并不是如原博文中那样。
- Java观察者模式 java.util.Observable 与 java.util.Observer 的理解及测试实例
- Java观察者模式 java.util.Observable 与 java.util.Observer 的理解
- Java观察者模式 java.util.Observable 与 java.util.Observer 的理解
- Java观察者模式 java.util.Observable 与 java.util.Observer 的理解
- Java观察者模式 java.util.Observable 与 java.util.Observer 的理解
- 观察者模式 java.util.Observable 与 java.util.Observer 的理解
- 用java.util.Observable实现Observer模式
- 用java.util.Observable实现Observer模式
- Java观察者模式 : Observer / Observable
- java 观察者模式Observable Observer
- 【jdk源码解析一】java.util.Observer与java.util.Observable
- java observer和observable 实现观察者模式
- 观察者模式-java 内置 Observable 和 Observer
- Java观察者模式 Observable Observer [U01]
- Java基础之Observable与Observer接口观察者模式
- [置顶] Java Observer与Observable实现观察者模式
- 【 应用以及剖析】之 java.util.Observer 观察者模式实现
- Java 语言使用 Observer/Observable 实现简单的观察者模式
- IOS 申请发布证书图文详解
- 在linux环境下部署伪分布式hadoop遇到的问题
- 静态链表
- 奇异值分解与PCA
- 网络垃圾的来源和处理措施详解
- Java观察者模式 java.util.Observable 与 java.util.Observer 的理解及测试实例
- 第三周作业
- 创业失败的七个原因及解决之道
- 第四周作业
- 【python】中文乱码问题
- 小朋友排队
- 存储系统在视频监控领域中的应用
- Java中的构造器、非静态初始化块和静态初始化块
- 第五周作业