java设计模式引入到设计中_Java设计模式(十)

Java设计模式(十)

------------观察者模式

引入

我们这里利用《Head.First.设计模式》中的那个气象站的经典的例子坐引。

我们需要建立一个该气象站,它必须建立在我们专利申请中的WeatherD ata对象上,由WeatherData对象负责追踪目前的天气状况(温度、湿度、气压)。我们还要建立一个应用,有三种布告板,分别显示目前的状况、气象统计及简单的预报。当WeatherObject对象获得最新的测量数据时,三种布告板必须实时更新。

而且,我们还希望它是一个可以扩展的气象站,也就是允许其他开发人员可以写出自己的气象布告板,并插入此应用中。

好了,下面的例子我们都将围绕这个例子进行。

定义与角色

定义

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

角色

抽象主题角色

publicinterfaceSubject {

publicvoidaddObserver(Observer o);

publicvoidremoveObserver(Observer o);

publicvoidnotifyObserver();

}

具体主题角色

publicclassWeatherDataimplementsSubject {

Listlisteners=newArrayList();

publicintgetTemperature() {

return0;

}

publicdoublegetHumidity() {

return0.53;

}

intgetPressure() {

return30;

}

//对外暴露接口

publicvoidmeasurementsChanged() {

this.notifyObserver();

}

@Override

publicvoidaddObserver(Observer o) {

//TODOAuto-generated method stub

listeners.add(o);

}

@Override

publicvoidnotifyObserver() {

//TODOAuto-generated method stub

intt =this.getTemperature();

doubleh =this.getHumidity();

intp =this.getPressure();

for(inti = 0; i

Observer listener =listeners.get(i);

listener.onWebtherChange(t, h, p);

}

}

@Override

publicvoidremoveObserver(Observer o) {

//TODOAuto-generated method stub

listeners.remove(o);

}

}

抽象观察者角色

publicinterfaceObserver {

publicvoidonWebtherChange(intt,doubleh,intp);

}

具体观察者角色

publicclassHWeatherPanelimplementsObserver {

publicWeatherDatadata;

publicHWeatherPanel(WeatherData data) {

this.data= data;

data.addObserver(this);

}

@Override

publicvoidonWebtherChange(intx,doubleh,intp) {

//TODOAuto-generated method stub

System.out.println("更新湿度面板,最湿度是"+ h);

}

}

publicclassPWeatherPanelimplementsObserver {

publicWeatherDatadata;

publicPWeatherPanel(WeatherData data) {

this.data= data;

data.addObserver(this);

}

@Override

publicvoidonWebtherChange(intx,doubleh,intp) {

//TODOAuto-generated method stub

System.out.println("更新压力面板,最新压力是"+ p);

}

}

publicclassTWeatherPanelimplementsObserver {

publicWeatherDatadata;

publicTWeatherPanel(WeatherData data) {

this.data= data;

data.addObserver(this);

}

@Override

publicvoidonWebtherChange(intx,doubleh,intp) {

//TODOAuto-generated method stub

System.out.println("更新温度面板,最新温度是"+ x);

}

}

客户调用

publicclassMyTest {

/**

*@paramargs

*/

publicstaticvoidmain(String[] args) {

//TODOAuto-generated method stub

WeatherData data =newWeatherData();

HWeatherPanel hp =newHWeatherPanel(data);

PWeatherPanel pp =newPWeatherPanel(data);

TWeatherPanel tp =newTWeatherPanel(data);

data.measurementsChanged();

}

}

打印结果:

更新湿度面板,最湿度是0.53

更新压力面板,最新压力是30

更新温度面板,最新温度是0

Java中内置的观察者模式

到目前为止,我们已经从无到有地完成了观察者模式,但是,JavaAAPI有内置的观察者模式。java.util包(package)内包含最基本的Observer接口与Observable类,这和我们的Subject接口与Observer接口很相似。Observer接口与Observable类使用上更方便,因为许多功能都已经事先准备好了。

使用

接口Observer

一个可在观察者要得到observable对象更改通知时可实现Observer接口的类。

很显然 这个Observer接口就是对应我们自己实现中的Observer接口,(o,arg)方法就对应我们的onWebtherChange(intt,doubleh,intp)方法,这与我们的想法甚至名称都是一致的。

类Observable

方法摘要

void

(o)如果观察者与集合中已有的观察者不同,则向对象的观察者集中添加此观察者。

protected  void

()指示对象不再改变,或者它已对其所有的观察者通知了最近的改变,所以hasChanged方法将返回false。

int

()返回Observable对象的观察者数目。

void

void

()清除观察者列表,使此对象不再有任何观察者。

boolean

()测试对象是否改变。

void

()如果hasChanged方法指示对象已改变,则通知其所有观察者,并调用clearChanged方法来指示此对象不再改变。

void

(arg)如果hasChanged方法指示对象已改变,则通知其所有观察者,并调用clearChanged方法来指示此对象不再改变。

protected  void

()标记此Observable对象为已改变的对象;现在hasChanged方法将返回true。

由上表可以看出Observable类对应我们自己实现中的Subject接口,由于它是一个类,对于想要扩展的朋友就显得无能为力了,但是对于一般的观察者应用已经足够使了。

区别

我们不难发现,这个函数表中多个一个change的概念((),(),())它的引入是为了在更新观察者时,有更多的弹性,你可以更适当地通知观察者。比方说,如果没有setChanged()方法,我们的气象站测量是如此敏锐,以致于温度计读数每十分之一度就会更新,这会造成WeatherData对象持续不断地通知观察者,我们并不希望看到这样的事情发生。如果我们希望半度以上才更新,就可以在温度差距到达半度时,调用setChanged(),进行有效的更新。你也许不会经常用到此功能,但是把这样的功能准备好,当需要时马上就可以使用。总之,你需要调用setChanged(),以便通知开始运转。如果此功能在某些地方对你有帮助,你可能也需要clearChanged()方法,将changed状态设置回false。另外也有一个hasChanged()方法,告诉你changed标志的当前状态。

总结

优势

主题对象与观察者对象之间的松耦合,主题对象只知道Obserser接口,并不关谁实现了该接口以及怎么实现的,一旦有新类型观察者出现,我们只要把它注册到主题中就可以了,不用修改任何代码。

主要程序设计应用

这种设计模式广泛用于数据或状态的变化引起的界面刷新工作。

比如一个股票数据(价格)发生变化,可能会影响几个视图的更新(实时图,表图,甚至要入库操作。。。),我们就需要把这几个视图和操纵数据库的类作为观察者,注册到相应主题中去。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值