JAVA观察者模式详解包含观察者模式JDK的漏洞以及事件驱动模型Word文档下载推荐.doc
- 文档编号:13161433
- 上传时间:2022-10-07
- 格式:DOC
- 页数:18
- 大小:287KB
JAVA观察者模式详解包含观察者模式JDK的漏洞以及事件驱动模型Word文档下载推荐.doc
《JAVA观察者模式详解包含观察者模式JDK的漏洞以及事件驱动模型Word文档下载推荐.doc》由会员分享,可在线阅读,更多相关《JAVA观察者模式详解包含观察者模式JDK的漏洞以及事件驱动模型Word文档下载推荐.doc(18页珍藏版)》请在冰豆网上搜索。
可以看到,我们的被观察者类Observable只关联了一个Observer的列表,然后在自己状态变化时,使用notifyObservers方法通知这些Observer,具体这些Observer都是什么,被观察者是不关心也不需要知道的。
上面就将观察者和被观察者二者的耦合度降到很低了,而我们具体的观察者是必须要知道自己观察的是谁,所以它依赖于被观察者。
下面LZ给写出一个很简单的观察者模式,来使用JAVA代码简单诠释一下上面的类图。
首先是观察者接口。
packagenet;
//这个接口是为了提供一个统一的观察者做出相应行为的方法
publicinterfaceObserver{
voidupdate(Observableo);
}
再者是具体的观察者。
publicclassConcreteObserver1implementsObserver{
publicvoidupdate(Observableo){
System.out.println("
观察者1观察到"
+o.getClass().getSimpleName()+"
发生变化"
);
观察者1做出相应"
publicclassConcreteObserver2implementsObserver{
观察者2观察到"
观察者2做出相应"
下面是被观察者,它有一个观察者的列表,并且有一个通知所有观察者的方法,通知的方式就是调用观察者通用的接口行为update方法。
下面我们看它的代码。
importjava.util.ArrayList;
importjava.util.List;
publicclassObservable{
List<
Observer>
observers=newArrayList<
();
publicvoidaddObserver(Observero){
observers.add(o);
publicvoidchanged(){
我是被观察者,我已经发生变化了"
notifyObservers();
//通知观察自己的所有观察者
publicvoidnotifyObservers(){
for(Observerobserver:
observers){
observer.update(this);
这里面很简单,新增两个方法,一个是为了改变自己的同时通知观察者们,一个是为了给客户端一个添加观察者的公共接口。
下面我们使用客户端调用一下,看一下客户端如何操作。
publicclassClient{
publicstaticvoidmain(String[]args)throwsException{
Observableobservable=newObservable();
observable.addObserver(newConcreteObserver1());
observable.addObserver(newConcreteObserver2());
observable.changed();
运行结果如下。
可以看到我们在操作被观察者时,只要调用changed方法,观察者们就会做出相应的动作,而添加观察者这个行为算是准备阶段,将具体的观察者关联到被观察者上面去。
缪买网
下面LZ给出一个有实际意义的例子,比如我们经常看的小说网站,都有这样的功能,就是读者可以订阅作者,这当中就有明显的观察者模式案例,就是作者和读者。
他们的关系是一旦读者关注了一个作者,那么这个作者一旦有什么新书,就都要通知读者们,这明显是一个观察者模式的案例,所以我们可以使用观察者模式解决。
由于JDK中为了方便开发人员,已经写好了现成的观察者接口和被观察者类,下面LZ先给出JDK中现成的观察者和被观察者代码,外加自己的一点解释,来帮助一些读者对JDK中对观察者模式的支持熟悉一下。
先来观察者接口。
//观察者接口,每一个观察者都必须实现这个接口
//这个方法是观察者在观察对象产生变化时所做的响应动作,从中传入了观察的对象和一个预留参数
voidupdate(Observableo,Objectarg);
下面是被观察者类。
importjava.util.Vector;
//被观察者类
//这是一个改变标识,来标记该被观察者有没有改变
privatebooleanchanged=false;
//持有一个观察者列表
privateVectorobs;
publicObservable(){
obs=newVector();
//添加观察者,添加时会去重
publicsynchronizedvoidaddObserver(Observero){
if(o==null)
thrownewNullPointerException();
if(!
obs.contains(o)){
obs.addElement(o);
//删除观察者
publicsynchronizedvoiddeleteObserver(Observero){
obs.removeElement(o);
//notifyObservers(Objectarg)的重载方法
notifyObservers(null);
//通知所有观察者,被观察者改变了,你可以执行你的update方法了。
publicvoidnotifyObservers(Objectarg){
//一个临时的数组,用于并发访问被观察者时,留住观察者列表的当前状态,这种处理方式其实也算是一种设计模式,即备忘录模式。
Object[]arrLocal;
//注意这个同步块,它表示在获取观察者列表时,该对象是被锁定的
//也就是说,在我获取到观察者列表之前,不允许其他线程改变观察者列表
synchronized(this){
//如果没变化直接返回
changed)
return;
//这里将当前的观察者列表放入临时数组
arrLocal=obs.toArray();
//将改变标识重新置回未改变
clearChanged();
//注意这个for循环没有在同步块,此时已经释放了被观察者的锁,其他线程可以改变观察者列表
//但是这并不影响我们当前进行的操作,因为我们已经将观察者列表复制到临时数组
//在通知时我们只通知数组中的观察者,当前删除和添加观察者,都不会影响我们通知的对象
for(inti=arrLocal.length-1;
i>
=0;
i--)
((Observer)arrLocal[i]).update(this,arg);
//删除所有观察者
publicsynchronizedvoiddeleteObservers(){
obs.removeAllElements();
//标识被观察者被改变过了
protectedsynchronizedvoidsetChanged(){
changed=true;
//标识被观察者没改变
protectedsynchronizedvoidclearChanged(){
changed=false;
//返回被观察者是否改变
publicsynchronizedbooleanhasChanged(){
returnchanged;
//返回观察者数量
publicsynchronizedintcountObservers(){
returnobs.size();
被观察者除了一点同步的地方需要特殊解释一下,其余的相信各位都能看明白各个方法的用途。
其实上述JDK的类是有漏洞的,或者说,在我们使用观察者模式时要注意一个问题,就是notifyObservers这个方法中的这一段代码。
在循环遍历观察者让观察者做出响应时,JDK没有去抓取update方法中的异常,所以假设在这过程中有一个update方法抛出了异常,那么剩下还未通知的观察者就全都通知不到了,所以LZ个人比较疑惑这样的用意(LZ无法想象JAVA类库的制造者没考虑到这个问题),是sun当时真的忘了考虑这一点,还是另有它意?
当然各位读者如果有自己的见解可以告知LZ,不过LZ认为,不管是sun如此做是别有用意,还是真的欠考虑,我们都要注意在update方法里一定要处理好异常,个人觉得JDK中比较保险的做法还是如下这样。
i--){
try{
}catch(Throwablee){e.printStackTrace();
这样无论其中任何一个update是否成功都不会影响其余的观察者进行更新状态,我们自己比较保险的做法就是给update方法整个加上try块,或者确认不会发生运行时异常。
上面LZ和各位一起分析了JDK中观察者模式的源码,下面我们就拿上述小说网的例子,做一个DEMO。
首先要搞清楚在读者和作者之间是谁观察谁,很明显,应该是读者观察作者。
所以作者是被观察者,读者是观察者,除了这两个类之外,我们还需要额外添加一个管理器帮我们管理下作者
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- JAVA 观察者 模式 详解 包含 JDK 漏洞 以及 事件 驱动 模型