设为首页 收藏本站
查看: 1319|回复: 0

[经验分享] Head First 设计模式——观察者模式(Observer Pattern)——Python实现(1)

[复制链接]

尚未签到

发表于 2017-5-8 08:25:23 | 显示全部楼层 |阅读模式
  本作品采用知识共享署名-非商业性使用-相同方式共享 3.0 Unported许可协议进行许可。允许非商业转载,但应注明作者及出处。

作者:liuyuan_jq

2011-06-13


观察者模式定义

定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖都会收到通知并自动更新。观察者模式提供了一种对象设计,让主题和观察者之间松耦合。



设计原则

  为了交互对象之间的松耦合设计而努力。松耦合的设计之所以能让我们建立有弹性的系统,能够应对变化,是因为对象之间的互相依赖降到了最低。
问题
  建立下一代Internet气象观察站,该气象站必须建立在我们专利申请中的WeatherData对象上,由WeatherData对象负责追踪目前的天气状况(温度,湿度,气压)。

  • 建立一个应用,有三种布告板,分别显示目前的状态、气象统计及简单的预报。
  • 当WeatherObject对象获得最新的测量数据时,三种布告板必须实时更新。
  • 公布一组API,让其他开发人员可以写出自己的气象布告板。
设计气象站
  WeatherData实现Subject接口
  class Subject(object):"""主题接口类"""def registerObserver(observer):raise NotImplementedError("abstract Subject")def removeObserver(observer):raise NotImplementedError("abstract Subject")def notifyObservers(self):raise NotImplementedError("abstract Subject")
  气象组件实现观察者接口
  class Observer(object):"""观察者接口类"""def update(temp, humidity, pressure):raise NotImplementedError("abstract Observer")
  布告栏显示接口
  class DisplayElement(object):def display(self):raise NotImplementedError("abstract DisplayElement")
源代码具体实现
  subject.py
  #!/usr/bin/env python# -*- coding:utf-8 -*-class Subject(object):"""主题接口类"""def registerObserver(observer):raise NotImplementedError("abstract Subject")def removeObserver(observer):raise NotImplementedError("abstract Subject")def notifyObservers(self):raise NotImplementedError("abstract Subject")
  observer.py
  #!/usr/bin/env python# -*- coding:utf-8 -*-class Observer(object):"""观察者接口类"""def update(temp, humidity, pressure):raise NotImplementedError("abstract Observer")
  weatherData.py
  #!/usr/bin/env python# -*- coding:utf-8 -*-from subject import Subjectclass WeatherData(Subject):"""天气数据类,是一个主题类"""# 类静态成员observers = []def __init__(self):self.temperature = 0.0self.humidity    = 0.0self.pressure    = 0.0def registerObserver(self, observer):"""注册观察者对象"""self.observers.append(observer)def removeObserver(self, observer):"""注销观察者对象"""self.observers.remove(observer)def notifyObservers(self):"""通知所有的观察者对象"""for observer in self.observers:observer.update(self.temperature, self.humidity, self.pressure)def measurementsChanged(self):self.notifyObservers()def setMeasurements(self, temperature, humidity, pressure):self.temperature = temperatureself.humidity    = humidityself.pressure    = pressureself.measurementsChanged()def getTemperature(self):return self.temperaturedef getHumidity(self):return self.humiditydef getPressure(self):return self.pressure
  displayElement.py
  #!/usr/bin/env python# -*- coding:utf-8 -*-from observer import Observerfrom weatherData import WeatherDataclass DisplayElement(object):def display(self):raise NotImplementedError("abstract DisplayElement")class CurrentConditionsDisplay(Observer, DisplayElement):"""目前状况布告板"""def __init__(self, weatherData):self.weatherData = weatherDataself.weatherData.registerObserver(self)def update(self, temperature, humidity, pressure):self.temperature = temperatureself.humidity    = humidityself.display()def display(self):print("Current conditions: " + str(self.temperature) + "F degrees and " + str(self.humidity) + "% humidity")class ForecastDisplay(Observer, DisplayElement):"""天气预报布告板"""def __init__(self, weatherData):self.weatherData = weatherDataself.currentPressure = 29.92self.weatherData.registerObserver(self)def update(self, temp, humidity, pressure):self.lastPressure    = self.currentPressureself.currentPressure = pressureself.display()def display(self):print("Forecast: ");if self.currentPressure > self.lastPressure:print("Improving weather on the way!")elif self.currentPressure == self.lastPressure:print("More of the same")elif self.currentPressure < self.lastPressure:print("Watch out for cooler, rainy weather")class StatisticsDisplay(Observer, DisplayElement):"""气象统计布告板"""def __init__(self, weatherData):self.maxTemp = 0.0self.minTemp = 200self.tempSum = 0.0self.numReadings = 0self.weatherData = weatherDataself.weatherData.registerObserver(self)def update(self, temp, humidity, pressure):self.tempSum += tempself.numReadings += 1if temp > self.maxTemp:self.maxTemp = tempif temp < self.minTemp:self.minTemp = tempself.display()def display(self):print("Avg/Max/Min temperature = " + str(self.tempSum / self.numReadings)+ "/" + str(self.maxTemp) + "/" + str(self.minTemp))class HeatIndexDisplay(Observer, DisplayElement):"""酷热指数布告板"""def __init__(self, weatherData):self.weatherData = weatherDataself.weatherData.registerObserver(self)self.heatIndex = 0.0def update(self, t, rh, pressure):self.heatIndex = self._computeHeatIndex(t, rh)self.display()def _computeHeatIndex(self, t, rh):index = ((16.923 + (0.185212 * t) + (5.37941 * rh) - (0.100254 * t * rh) + (0.00941695 * (t * t)) + (0.00728898 * (rh * rh)) + (0.000345372 * (t * t * rh)) - (0.000814971 * (t * rh * rh)) +(0.0000102102 * (t * t * rh * rh)) - (0.000038646 * (t * t * t)) + (0.0000291583 * (rh * rh * rh)) + (0.00000142721 * (t * t * t * rh)) + (0.000000197483 * (t * rh * rh * rh)) - (0.0000000218429 * (t * t * t * rh * rh)) +0.000000000843296 * (t * t * rh * rh * rh)) -(0.0000000000481975 * (t * t * t * rh * rh * rh)))return float(index)def display(self):print("Heat index is " + str(self.heatIndex))
  测试
  weatherStation.py
  #!/usr/bin/env python# -*- coding:utf-8 -*-from weatherData import WeatherDatafrom displayElement import *weatherData = WeatherData()currentDisplay    = CurrentConditionsDisplay(weatherData)statisticsDisplay = StatisticsDisplay(weatherData)forecastDisplay   = ForecastDisplay(weatherData)weatherData.setMeasurements(80, 65, 30.4)weatherData.setMeasurements(82, 70, 29.2)weatherData.setMeasurements(78, 90, 29.2)
  Current conditions: 80F degrees and 65% humidityAvg/Max/Min temperature = 80.0/80/80Forecast: Improving weather on the way!Current conditions: 82F degrees and 70% humidityAvg/Max/Min temperature = 81.0/82/80Forecast: Watch out for cooler, rainy weatherCurrent conditions: 78F degrees and 90% humidityAvg/Max/Min temperature = 80.0/82/78Forecast: More of the same
  weatherStationHeatIndex.py
  #!/usr/bin/env python# -*- coding:utf-8 -*-from weatherData import WeatherDatafrom displayElement import *weatherData = WeatherData()currentDisplay    = CurrentConditionsDisplay(weatherData)statisticsDisplay = StatisticsDisplay(weatherData)forecastDisplay   = ForecastDisplay(weatherData)heatIndexDisplay  = HeatIndexDisplay(weatherData)weatherData.setMeasurements(80, 65, 30.4)weatherData.setMeasurements(82, 70, 29.2)weatherData.setMeasurements(78, 90, 29.2)
  Current conditions: 80F degrees and 65% humidityAvg/Max/Min temperature = 80.0/80/80Forecast: Improving weather on the way!Heat index is 82.9553506371Current conditions: 82F degrees and 70% humidityAvg/Max/Min temperature = 81.0/82/80Forecast: Watch out for cooler, rainy weatherHeat index is 86.9012330639Current conditions: 78F degrees and 90% humidityAvg/Max/Min temperature = 80.0/82/78Forecast: More of the sameHeat index is 83.6496713956

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-374409-1-1.html 上篇帖子: ·python·用生成器和迭代器实现自己的xrange 下篇帖子: Python:通过远程监控用户输入来获取淘宝账号和密码的实验(二)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表