{privatefloattemperature;privatefloathumidity;private-Read.ppt

上传人:ga****84 文档编号:329845 上传时间:2018-09-22 格式:PPT 页数:39 大小:188.50KB
下载 相关 举报
{privatefloattemperature;privatefloathumidity;private-Read.ppt_第1页
第1页 / 共39页
{privatefloattemperature;privatefloathumidity;private-Read.ppt_第2页
第2页 / 共39页
{privatefloattemperature;privatefloathumidity;private-Read.ppt_第3页
第3页 / 共39页
{privatefloattemperature;privatefloathumidity;private-Read.ppt_第4页
第4页 / 共39页
{privatefloattemperature;privatefloathumidity;private-Read.ppt_第5页
第5页 / 共39页
点击查看更多>>
资源描述

1、The Observer Pattern(观察者模式),问题。,在日常生活中,常常会用这样的情形:当某件事发生时,应该通知所有的相关者。例如,如果我们的课程改变时间或地点,就应该通知所有选修了这门课程的同学。在软件设计中,也有类似的问题:当一个对象的状态发生变化时,如何能够通知与其相关的所有其他对象,而不用修改该对象的代码?,观察者模式(the Observer Pattern)就是用来解决此类问题的。,下面我们来看一个例子,一封商业信函嘿嘿,机会来了!,阿毛网络技术有限公司: 恭喜贵公司被选中开发我们的下一代基于因特网的天气监测系统。 该系统将基于我们拥有专利的气象数据对象来提供各种气象报告

2、(气象数据对象收集当前的气象数据,包括温度、湿度和气压)。初期要求提供三类报告:当前天气情况、气象统计报告和气象预报,这些报告都要在气象数据对象获得最新监测数据后得到实时更新。 另外,我们要求这个系统是可扩展的,希望发布一个API使得其他开发者也能编写他们自己的气象报告加入到我们的系统中。希望你们能提供这个API。 我们认为这是一个很好的商机,如果客户上勾了,我们就将对他们使用的每一种报告方式收费。你们可以以入股的方式加入到我们发财的行列。 期待尽早看到你们的设计和alpha版应用。 想发财气象服务有限公司CEO 李阿狗,瞧这记性!,呵呵。 刚才忘了把气象数据对象(WeatherData.ja

3、va)的源代码发给你们。 请查收。 李阿狗,气象监测系统概况,湿度传感器,温度传感器,气压传感器,气象站,WeatherDataobject,天气预报:明天下刀子,请预备铁锅!,想发财气象服务公司提供的部分,我们要实现的部分,抽取数据,显示报告,显示设备有三种显示报告,看看李阿狗的WeatherData.java,/*当气象测量数据改变时调用该方法*/Public void measurementsChanged()/在此编写你的代码,我们的任务就是实现measurementsChanged(),让他更新当前天气、天气统计、天气预报三种报告,我们到现在为止知道些什么呢?,WeatherData

4、类定义了获得温度、湿度和气压的方法。只要有新的气象数据measurementsChanged()方法就会被调用我们需要使用气象数据来提供三种报告,并且,每当WeatherData有新的数据时这三种报告就要更新。我们要开发的系统必须是可扩展的。其他开发者可以建立定制的报告,用户可以随意增减他们需要的报告。目前,我们只知道三种报告类型:当前天气情况、气象统计报告、天气预报。,我们自然会想到下面的解决方案,Public class WeatherData /声明实例变量Public void measurementsChanged() float temp=getTemperature(); flo

5、at humidity = getHumidity(); float pressure=getPressure(); currentConditionDisplay.update(temp,humidity,pressure); statisticsDisplay.update(temp,humidity,pressure); forecastDisplay.update(temp,humidity,pressure);/其他方法,获得最新的气象数据,调用每个报告对象,更新显示,因为气象数据发生变化时measurementsChanged()会自动被执行,所以,这个解决方案好吗?,Public

6、 class WeatherData /声明实例变量Public void measurementsChanged() float temp=getTemperature(); float humidity = getHumidity(); float pressure=getPressure(); currentConditionDisplay.update(temp,humidity,pressure); statisticsDisplay.update(temp,humidity,pressure); forecastDisplay.update(temp,humidity,pressu

7、re);/其他方法,是针对实现编程还是针对接口编程?每增加一个新的报告我们都必须修改代码吗?在运行时我们能动态增加或取消某类报告吗?,我们的问题在那里?,Public class WeatherData /声明示例变量Public void measurementsChanged() float temp=getTemperature(); float humidity = getHumidity(); float pressure=getPressure(); currentConditionDisplay.update(temp,humidity,pressure); statistics

8、Display.update(temp,humidity,pressure); forecastDisplay.update(temp,humidity,pressure);/其他方法,由于是对具体实现的编程,所以不修改程序我们无法增加或删除报告,设计原则,将变化部分与固定不变的部分相分离。对该原则的另一种理解是:将变化的部分拿出来进行封装,以便以后你可以修改它而不会影响那些不变的部分。这一原则几乎是所有设计模式的基础,所有设计模式都提供了这样一种机制:让系统的某些部分独立于其他部分变化。,看看现实生活中类似的情况,报纸订阅,发行站,订阅者1,订阅者n,退订者,新报纸,发行站+订阅者们=Obs

9、erver Pattern,观察者模式的定义,观察者模式定义了对象间的一对多依赖关系。当一方的对象改变状态时,所有的依赖者都会被通知并自动被更新。在观察者模式中,被依赖的一方叫做目标或主题(Subject),依赖方叫做观察者(Observers)。,报纸订阅de情况,谁是目标,谁是观察者?,目标,观察者1,观察者n,通知,观察者模式一种更好理解的名字是:发布-订阅模式(Publish-Subscribe),观察者模式的基本类图,设计原则,对接口编程,而不是对实现编程。(Program to an interface, not an implementation),观察者模式的基本类图,根据主题

10、状态的变化更新自身的状态,对所有的观察者对象oo.update(),设置/获得状态数据,设计我们的应用,observers,subject,高质量设计的原则-松耦合(loose Coupling),如果两个对象是松耦合的,则他们可以相互作用,但彼此的依赖性很小。观察者模式符合松耦合的原则。因为:主题(subject)只需要知道其观察者(Observer)实现了某个接口。可以随时加入观察者。不需要修改主题就可以加入新的类型的观察者主题和观察者都可以独立地被复用修改主题或观察者都不会影响另一方。观察者之间互不相干。,编写代码,/ Subject.javapublic interface Subje

11、ct public void registerObserver(Observer o); public void removeObserver(Observer o); public void notifyObservers(); / Observer.javapublic interface Observer public void update(float temp, float humidity, float pressure);/ DisplayElement .javapublic interface DisplayElement public void display();,编写代

12、码,/ WeatherData.javaimport java.util.ArrayList;public class WeatherData implements Subject private ArrayList observers; private float temperature; private float humidity; private float pressure; public WeatherData() /构造方法 observers = new ArrayList(); ,编写代码,/续WeatherData.java public void registerObse

13、rver(Observer o) observers.add(o); public void removeObserver(Observer o) int i = observers.indexOf(o); if (i = 0) observers.remove(i); ,编写代码,/续WeatherData.java public void notifyObservers() for (int i = 0; i observers.size(); i+) Observer observer = (Observer)observers.get(i); observer.update(tempe

14、rature, humidity, pressure); ,编写代码,/续WeatherData.java public void measurementsChanged() notifyObservers(); public void setMeasurements(float temperature, float humidity, float pressure) this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; measurementsChanged(); / other

15、 WeatherData methods here,编写代码,public class CurrentConditionsDisplay implements Observer, DisplayElement private float temperature; private float humidity; private Subject weatherData; public CurrentConditionsDisplay(Subject weatherData) this.weatherData = weatherData; weatherData.registerObserver(t

16、his); public void update(float temperature, float humidity, float pressure) this.temperature = temperature; this.humidity = humidity; display(); public void display() System.out.println(当前天气情况:气温 + temperature + 华氏度,湿度: + humidity + % ); ,编写代码,public class WeatherStation public static void main(Stri

17、ng args) WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData); ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData); weatherData.setMeas

18、urements(80, 65, 30.4f); weatherData.setMeasurements(82, 70, 29.2f); weatherData.setMeasurements(78, 90, 29.2f); ,思考与讨论:怎样加入第三方的报告,如果你是第三方,你要知道哪些信息才能编写你的第三方报告?,加入炎热指数报告,public class HeatIndexDisplay implements Observer, DisplayElement float heatIndex = 0.0f; private Subject weatherData; public HeatI

19、ndexDisplay(Subject weatherData) this.weatherData = weatherData; weatherData.registerObserver(this); public void update(float t, float rh, float pressure) heatIndex = computeHeatIndex(t, rh); display(); private float computeHeatIndex(float t, float rh) float index = 炎热指数计算公式; return index; public vo

20、id display() System.out.println(炎热指数(Heat index)为: + heatIndex); ,讨论:可不可以合并Observer和DisplayElement,observers,subject,讨论:具体报告类直接与WeatherData关联会怎么样?,observers,subject,讨论:取消Subject接口会怎么样?,observers,subject,总结:Observer模式,意图定义对象间的一种一对多的依赖关系。当一方的对象改变状态时,所有的依赖者都会得到通知并被自动更新。别名依赖(Dependents)发布-订阅(Publish-Sub

21、scribe)个人认为叫通知者模式可能更好理解。,总结:Observer模式-动机,将一个系统分割成一系列相互协作的类有一个常见的副作用:需要维护相关对象间的一致性。我们不希望为了维持一致性而使得各个类紧密耦合,导致可重用性的降低。观察者模式使得任意数目的观察者不必知道彼此的存在,且主题发生变化时都可以得到主题的通知,而同步改变状态。是一种很松的耦合。具有很好的可重用性。,总结:Observer模式-适用性,当一个抽象模型有两个方面,其中一个方面依赖于另一个方面时,将这两者封装在独立的对象中使他们可以独立的改变和复用。当一个对象的改变需要同时改变其他对象,而不知道具体有多少对象需要改变。当一个

22、对象必须通知其他对象,而他又不能假定其它对象是谁。,总结:Observer模式-结构,具体观察者,主题接口,具体主题,观察者接口,总结:Observer模式参与者,Subject(主题)知道它的观察者(观察者必须实现了一定的接口),可以有任意多个观察者。提供注册和注销观察者的接口Observer(观察者)为那些在主题发生变化时需要获得通知的对象定义一个更新(update)接口。ConcreteSubject(具体主题)保持实际状态数据,当状态发生变化时通知各观察者ConcreteObserver (具体观察者)维持一个指向具体主题对象的引用存储有关状态实现Observer的更新接口,使自身状态

23、与主题状态保持一致,习题(下周上机完成),设有一股票,其价格在一定范围内波动,股民需要三种报告:股票的当前价格;股票价格的统计分析报告(最低价、最高价、均价);股票价格趋势预测。请运用观察者模式,编写上述股票行情程序(模拟估价30次变动)。编写实验报告,要求画出相应的类图,提供java源程序。下下周3前上交至。提示:股价变动用随机数模拟:java.util.Random选做:查阅相关资料,了解Java JDK内置的观察者模式,解释它为什么有时候不好用。,如何产生随机数,/引入Random类:import java.util.Random;/在程序段中:final Random random = new Random();int x;float mm;for(int i=0;i10;i+)mm=random.nextFloat()*100; /浮点数x=random.nextInt(50); /整数,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 重点行业资料库 > 1

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。