必须做作业三:气象项目中观察者模式解析

观察者模式

定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。

观察者模式是一种对象行为型模式。

目的

建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应。在此,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展,这就是观察者模式的模式动机。

结构

观察者模式包含如下角色:

Subject: 目标

ConcreteSubject: 具体目标

Observer: 观察者

ConcreteObserver: 具体观察者

image

来源

示例

我们以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
    })

优点

当数据更新后,可以自动通知观察者

目标扩展性更强

实现了目标与观察者之间的抽象耦合

实现了广播通信

猜你喜欢

转载自www.cnblogs.com/cuiguohua/p/9838224.html