您好,欢迎访问三七文档
TheObserverPattern(观察者模式)问题。。。在日常生活中,常常会用这样的情形:当某件事发生时,应该通知所有的相关者。例如,如果我们的课程改变时间或地点,就应该通知所有选修了这门课程的同学。在软件设计中,也有类似的问题:当一个对象的状态发生变化时,如何能够通知与其相关的所有其他对象,而不用修改该对象的代码?实际问题股票行情与分析软件的设计股票行情发生变化了,软件必须让与该股票相关的各种指标报告也作相应的变化。证交所:提供基本的股票行情数据对象各软件开发商:设计自己的软件,提供各种指标分析报告。如何做到:不管你设计什么样的分析软件,行情数据对象不用修改。观察者模式(theObserverPattern)就是用来解决此类问题的。下面我们来看一个例子一封商业信函…嘿嘿,机会来了!阿毛网络技术有限公司:恭喜贵公司被选中开发我们的下一代基于因特网的天气监测系统。该系统将基于我们拥有专利的气象数据对象来提供各种气象报告(气象数据对象收集当前的气象数据,包括温度、湿度和气压)。初期要求提供三类报告:当前天气情况、气象统计报告和气象预报,这些报告都要在气象数据对象获得最新监测数据后得到实时更新。另外,我们要求这个系统是可扩展的,希望发布一个API使得其他开发者也能编写他们自己的气象报告加入到我们的系统中。希望你们能提供这个API。这是一个很好的商机,我们可以对客户使用的每一种报告方式收费。你们可以以入股的方式加入到我们发财的行列。期待尽早看到你们的设计和alpha版应用。想发财气象服务有限公司CEO李阿狗瞧这记性!呵呵。。。刚才忘了把气象数据对象(WeatherData.java)的源代码发给你们。请查收。李阿狗气象监测系统概况湿度传感器温度传感器气压传感器气象站WeatherDataobject天气预报:明天下刀子,出门请带铁锅!想发财气象服务公司提供的部分我们要实现的部分抽取数据显示报告显示设备有三种显示报告看看李阿狗的WeatherData.javaWeatherDatagetTemperature()getHumidity()getPressure()measurementsChanged()//othermethods/*当气象测量数据改变时调用该方法*/PublicvoidmeasurementsChanged(){//在此编写你的代码}我们的任务就是实现measurementsChanged(),让他更新当前天气、天气统计、天气预报三种报告现有的基础和需求情况已知WeatherData类定义了获得温度、湿度和气压的方法。只要有新的气象数据measurementsChanged()方法就会被调用我们需要使用气象数据来提供三种报告,并且,每当WeatherData有新的数据时这三种报告就要更新。我们要开发的系统必须是可扩展的。其他开发者可以建立定制的报告,用户可以随意增减他们需要的报告。目前,我们只知道三种报告类型:当前天气情况、气象统计报告、天气预报。我们自然会想到下面的解决方案PublicclassWeatherData{//声明实例变量…PublicvoidmeasurementsChanged(){floattemp=getTemperature();floathumidity=getHumidity();floatpressure=getPressure();currentConditionDisplay.update(temp,humidity,pressure);statisticsDisplay.update(temp,humidity,pressure);forecastDisplay.update(temp,humidity,pressure);}//其他方法}获得最新的气象数据调用每个报告对象,更新显示WeatherDatagetTemperature()getHumidity()getPressure()measurementsChanged()//othermethods因为气象数据发生变化时measurementsChanged()会自动被执行,所以…这个解决方案好吗?PublicclassWeatherData{//声明实例变量…PublicvoidmeasurementsChanged(){floattemp=getTemperature();floathumidity=getHumidity();floatpressure=getPressure();currentConditionDisplay.update(temp,humidity,pressure);statisticsDisplay.update(temp,humidity,pressure);forecastDisplay.update(temp,humidity,pressure);}//其他方法}是针对实现编程还是针对接口编程?每增加一个新的报告我们都必须修改代码吗?在运行时我们能动态增加或取消某类报告吗?我们的问题在那里?PublicclassWeatherData{//声明示例变量PublicvoidmeasurementsChanged(){floattemp=getTemperature();floathumidity=getHumidity();floatpressure=getPressure();currentConditionDisplay.update(temp,humidity,pressure);statisticsDisplay.update(temp,humidity,pressure);forecastDisplay.update(temp,humidity,pressure);}//其他方法}由于是对具体实现的编程,所以不修改程序我们无法增加或删除报告变化的部分应该加以封装看起来我们是用一个公用接口来与现实报告打交道设计原则将变化部分与固定不变的部分相分离。对该原则的另一种理解是:将变化的部分拿出来进行封装,以便以后你可以修改它而不会影响那些不变的部分。这一原则几乎是所有设计模式的基础,所有设计模式都提供了这样一种机制:让系统的某些部分独立于其他部分变化。看看现实生活中类似的情况报纸订阅发行站订阅者1订阅者n退订者新报纸发行站+订阅者们=ObserverPattern观察者模式的定义观察者模式定义了对象间的一对多依赖关系。当一方的对象改变状态时,所有的依赖者都会被通知并自动被更新。在观察者模式中,被依赖的一方叫做目标或主题(Subject),依赖方叫做观察者(Observers)。报纸订阅de情况谁是目标,谁是观察者?目标观察者1观察者n通知观察者模式一种更好理解的名字是:发布-订阅模式(Publish-Subscribe)观察者模式的基本类图SubjectregisterObserver()removeObserver()notifyObserver()Observer1update()Observer2update()设计原则对接口编程,而不是对实现编程。(Programtoaninterface,notanimplementation)观察者模式的基本类图《interface》SubjectregisterObserver()removeObserver()notifyObserver()ConcreteSubjectregisterObserver()removeObserver()notifyObserver()getState()setState()《interface》Observerupdate()ConcreteObserverupdate()//otherObserver//specificmethods根据主题状态的变化更新自身的状态对所有的观察者对象oo.update()设置/获得状态数据设计我们的应用《interface》SubjectregisterObserver()removeObserver()notifyObserver()WeatherDataregisterObserver()removeObserver()notifyObserver()geTemperature()getHumidity()getPressure()measurementsChanged()《interface》Observerupdate()CurrentconditionsDisplayupdate()Display(){//displaycurrent//measurementsStatisticsDisplayupdate()Display(){//displayaverage,…//measurementsThirdPartyDisplayupdate()Display(){//displaysomething//basedonmeasurements《interface》DisplayElementdisplay()observers高质量设计的原则---松耦合(looseCoupling)如果两个对象是松耦合的,则他们可以相互作用,但彼此的依赖性很小。观察者模式符合松耦合的原则。因为:主题(subject)只需要知道其观察者(Observer)实现了某个接口。可以随时加入观察者。不需要修改主题就可以加入新的类型的观察者主题和观察者都可以独立地被复用修改主题或观察者都不会影响另一方。观察者之间互不相干。编写代码//Subject.javapublicinterfaceSubject{publicvoidregisterObserver(Observero);publicvoidremoveObserver(Observero);publicvoidnotifyObservers();}//Observer.javapublicinterfaceObserver{publicvoidupdate(floattemp,floathumidity,floatpressure);}//DisplayElement.javapublicinterfaceDisplayElement{publicvoiddisplay();}编写代码//WeatherData.javaimportjava.util.ArrayList;publicclassWeatherDataimplementsSubject{privateArrayListobservers;privatefloattemperature;privatefloathumidity;privatefloatpressure;publicWeatherData()//构造方法{observers=newArrayList();}编写代码//续WeatherData.javapublicvoidregisterObserver(Observero){observers.add(o);}publicvoidremoveObserver(Observero){inti=observers.indexOf(o);if(i=0){observers.remove(i);}}编写代码//续WeatherData.javapublicvoidnotifyObservers(){for(inti=0;iobservers.size();i++){Observerobserver=(Observer)observers.get(i);observer.update(temperature,humidity,pressure);}}编写代码//续WeatherData.javapublicvoidmeasurementsChanged(){notifyObservers();}publicvoidsetMeasurements(floattemperature,f
本文标题:93观察者模式
链接地址:https://www.777doc.com/doc-3844552 .html