必须做作业三:气象项目中观察者模式解析
观察者模式
定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
观察者模式是一种对象行为型模式。
目的
建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应。在此,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展,这就是观察者模式的模式动机。
结构
观察者模式包含如下角色:
Subject: 目标
ConcreteSubject: 具体目标
Observer: 观察者
ConcreteObserver: 具体观察者
示例
我们以Github上的一个观察者模式的项目为例,见这里 。
该项目是一个气象更新显示系统,在气象站数据更新后,能够自动更新显示面板的信息。
源码分析
观察者观察的对象
称为可观察对象,需要实现具体的注册和删除管理者方法。
class AbstractObservable(object):
def register(self):
raise NotImplementedError(
'register is a abstract method which must be implemente')
def remove(self):
raise NotImplementedError(
'remove is a abstract method which must be implemente')
观察者抽象类
让可观察对象通知观察者
class AbstractDisplay(object):
def update(self):
raise NotImplementedError(
'update is a abstract method which must be implemente')
def display(self):
raise NotImplementedError(
'display is a abstract method which must be implemente')
Subject
用于管理多个事件的通知,管理多个可观察对象
class Subject(object):
def __init__(self, subject):
self.subject = subject
self._observers = []
def register(self, ob):
self._observers.append(ob)
def remove(self, ob):
self._observers.remove(ob)
def notify(self, data=None):
for ob in self._observers:
ob.update(data)
WeatherData
用于管理气象数据
https://github.com/zhengxiaowai/design-patterns/blob/master/behavioral/observer.py#L41
class WeatherData(AbstractObservable):
def __init__(self, *namespaces):
self._nss = {}
self._clock = None
self._temperature = None
self._humidity = None
self._oxygen = None
for ns in namespaces:
self._nss[ns] = Subject(ns)
......
......
OverviewDisplay
总览显示面板,获取当前数据并显示
class OverviewDisplay(AbstractDisplay):
def __init__(self):
self._data = {}
def update(self, data):
self._data = data
self.display()
def display(self):
print(u'总览显示面板:')
for k, v in self._data.items():
print(k + ': ' + str(v))
main 函数
借助观察者模式,气象数据更新后,可以通过可观察对象管理者的notify接口,通知观察者更新数据。
if __name__ == '__main__':
import time
# 生成一个可观察对象,支持('all', 'temperature', 'humidity', 'oxygen')的数据通知
wd = WeatherData('all', 'temperature', 'humidity', 'oxygen')
# 两个观察者对象
od = OverviewDisplay()
td = TemperatureDisplay()
# 注册到可观察对象中,能获取数据更新
wd.register('all', od)
wd.register('temperature', td)
# 更新数据,可观察对象将会自动更新数据
wd.set_measurement({
'clock': time.strftime("%Y-%m-%d %X", time.localtime()),
'temperature': 20,
'humidity': 60,
'oxygen': 10
})
# 一秒后再次更新数据
time.sleep(1)
print('\n')
wd.set_measurement({
'clock': time.strftime("%Y-%m-%d %X", time.localtime()),
'temperature': 21,
'humidity': 58,
'oxygen': 7
})
优点
当数据更新后,可以自动通知观察者
目标扩展性更强
实现了目标与观察者之间的抽象耦合
实现了广播通信
posted on 2018-10-23 18:05 cuiguohua1994 阅读(167) 评论(0) 编辑 收藏 举报