Java观察者模式 Observable Observer [U01]
来源:互联网 发布:js 垃圾回收机制 编辑:程序博客网 时间:2024/05/20 01:36
part1
JDK1.2后,Java提供了对观察者模式的支持接口和实现类。
其中接口java.util.Observer用来指定观察者,观察者必须实现 void update(Observable o, Object arg) 方法。
而java.util.Observable 用来指定观察物(被观察者、可被观察的),并且提供了一系列的方法。
读者可以很轻易的使用这个接口和实现类来实现观察者模式。
part2
java.util.Observer 只有一个简单的方法 void update(Observable o, Object arg)
其中,参数 Observable o 用于指定触发 update 方法的对象,Object arg 用于指定触发 update 方法时候的附加参数。
如果有桌面应用开发的读者应该很了解,这跟事件处理机制是完全一样的,其中 Observable o 可被看作事件源。
Object arg 可被看作消息。
part3
说了那么多,我们还是动手写个例子吧。这里我们以读者订阅杂志为例子。
package t2;import java.util.Observable;/** * 报社(发布新闻)(发布者) * 继承 * 可观察(被观察)类 * @author Zet * */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 t2;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Observable;import java.util.Observer;/** * 读者 实现 观察者模式 * * @author Zet * */public class Reader implements Observer { private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-DD HH:mm:ss"); private String name; public Reader(String name) { super(); this.name = name; } /** * 更新 */ @Override public void update(Observable o, Object arg) { if (o instanceof Publisher) { Publisher p = (Publisher) o; System.out.println("名称为" + this.name + " 看报者 于 " + sdf.format(new Date()) + " 订阅 " + p.getMagazineName()); } }}
package t2;import org.junit.Test;public class TestCase { @Test public void register() { Reader reader1 = new Reader("a reader"); Publisher publisher = new Publisher(); publisher.addObserver(reader1); publisher.publish("java技术"); }}
这里很清楚的看到,当出版社出版杂志的时候,会主动的告知读者,读者就会订阅杂志,这也是一种主动推送的模式。
part4
public void notifyObservers(Object arg)
传入的this,指的是参数
publisher.publish(“xxx”) // 发布事件 [发布报纸]
- setChanged() // changed = true [新报纸出炉]
- notifyObservers( (arg): this) // 通知[所有的]观察者 [准备送出报纸]
notifyObservers(this) //
- ((Observer)arrLocal[i]).update(this, (arg):arg) // for循环 [送出报纸到每一个订阅者手中]
这里大家会发现,调用 notifyObservers() 的时候,为什么传进当前对象this 呢?而这个this,我们在读者那也没用到啊。
这个问题曾经也让我觉得很苦恼,之前我也不清楚为什么观察者要拿到被观察对象的引用,但是,我们看看下面这个例子。
首先我们引用一个新的类:
package t2;import java.util.Observable;/** * 电视台(发布新闻)(发布者) * 继承 * 可观察(被观察)类 * @author Zet * */public class TVStation extends Observable { private String programmeName; public String getProgrammeName() { return programmeName; } public void play(String programmeName) { this.programmeName = programmeName; setChanged(); notifyObservers(this); }}
然后修改 Reader 和 TestCast:
package t2;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Observable;import java.util.Observer;/** * 读者 实现 观察者模式 * * @author Zet */public class Reader implements Observer { private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-DD HH:mm:ss"); private String name; public Reader(String name) { super(); this.name = name; } /** * 更新 */ @Override public void update(Observable o, Object arg) { if (o instanceof Publisher) { Publisher p = (Publisher) o; System.out.println("名称为" + this.name + " 看报者 于 " + sdf.format(new Date()) + " 订阅 " + p.getMagazineName()); } if (o instanceof TVStation) { TVStation t = (TVStation) o; System.out.println("名称为" + this.name + " 收看者 于 " + sdf.format(new Date()) + " 收看 " + t.getProgrammeName()); } }}
package t2;import org.junit.Test;public class TestCase { @Test public void register() { Reader reader1 = new Reader("a reader"); Publisher publisher = new Publisher(); publisher.addObserver(reader1); TVStation tvStation = new TVStation(); tvStation.addObserver(reader1); publisher.publish("java技术"); tvStation.play("java代码实战"); }}
最后我们可以看到,同一个观察者其实是可以注册到不同的(可观察)被观察者上面的,而传过来的 Observable o 其实可以用来检验到底是谁发过来的消息。
除此之外,我们还可以在接收到消息之后,进行撤销观察的工作。
package t2;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Observable;import java.util.Observer;/** * 读者 实现 观察者模式 * * @author Zet */public class Reader implements Observer { private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-DD HH:mm:ss"); private String name; public Reader(String name) { super(); this.name = name; } /** * 更新 */ @Override public void update(Observable o, Object arg) { if (o instanceof Publisher) { Publisher p = (Publisher) o; p.deleteObserver(this); System.out.println("名称为" + this.name + " 看报者 于 " + sdf.format(new Date()) + " 订阅 " + p.getMagazineName()); } if (o instanceof TVStation) { TVStation t = (TVStation) o;// t.deleteObserver(this); System.out.println("名称为" + this.name + " 收看者 于 " + sdf.format(new Date()) + " 收看 " + t.getProgrammeName()); } }}
通过 deleteObserver() 方法就可以撤销观察出版社对象。
开发工具
intellj idea
代码
https://github.com/dzetjava/javaDesignPattern/tree/master/learn_observer
来源:http://kentkwan.iteye.com/blog/739516
end
- Java观察者模式 Observable Observer [U01]
- Java观察者模式 : Observer / Observable
- java 观察者模式Observable Observer
- java observer和observable 实现观察者模式
- 观察者模式-java 内置 Observable 和 Observer
- 观察者模式(Observer、Observable)
- Observable与Observer (观察者模式)
- Java 语言使用 Observer/Observable 实现简单的观察者模式
- JAVA 观察者设计模式 Observable类 和 Observer接口
- Java基础之Observable与Observer接口观察者模式
- [置顶] Java Observer与Observable实现观察者模式
- Java_观察者模式(Observable和Observer)
- android Observable and Observer(观察者模式)
- 十一、观察者模式(Observable、Observer)
- android Observable and Observer(观察者模式)
- 利用Observable、Observer实现观察者模式
- Java_观察者模式(Observable和Observer)
- 浅谈 Observable和Observer 观察者模式
- JAVA学习笔记04封装,继承,多态
- 【复习笔记】被百度问过四次的进程与线程的关系
- hdu 2094 产生冠军
- bitset的用法
- Windows记事本UTF-8编码异常
- Java观察者模式 Observable Observer [U01]
- 找不到或无法加载主类
- 关于elastic search5.4.3安装过程中遇到的那些坑
- 浅析mybatis原理
- 使用options对象进行二次采样
- (矩阵快速幂)hdu5950 Recursive sequence
- hdoj-2005
- 射击课程微信预约-乐享其约
- 网络工程用UDP协议和多线程实现群聊。(用map来存取地址信息)