观察者模式,无需多线程完成数据监听

你们好,咱们今天来了解一个新的设计模式——观察者模式web

观察者模式的思路很简单,它被普遍地用在各类数据监控上。不少时候咱们但愿监听某个数据的变化,但愿一旦获悉它的变化以后当即采起一些举措。按照常规的操做,咱们须要开启额外的线程来进行监听。可是开启线程一则很是麻烦,二则须要带来额外的开销,咱们今天介绍的观察者模式就能够在无需多余开销的基础上完成这个功能设计模式

观察者

在观察者模式当中,整个运行流和常规的操做相反,咱们并非用一些程序去监听数据的变化。相反而是当数据发生变化的时候,咱们去通知对应的监听器数据产生了变化。好处咱们前面也说过了,能够避免多余的开销。app

首先,咱们来实现两个监听器。也就是当数据发生变化以后会触发这两个监听器。在这个设计模式当中,监听器被命名为viewer,这里的观察不是一种主动的观察而是一种被动地接收通知。也许是起名的人想不出更好的名字来吧,其实我以为应该叫作receiver更好。编辑器

class IncreaseViewer:

    def __init__(self):
        self.data = 0

    def update(self, subject):
        # 判断是否增长
        if subject.data > self.data:
            print('Increased: Subject {} data increased to {}'.format(subject.name, subject.data))
            self.data = subject.data


class DeclineViewer:

    def __init__(self):
        self.data = 0

    def update(self, subject):
        # 判断是否减小
        if subject.data < self.data:
        print('Decreased: Subject %s data decreased to %d' % (subject.name, subject.data))
        self.data = subject.data

数据

观察者的代码应该很好理解,理解了观察者类以后,咱们再来看看数据类。函数

数据的类其实也很简单,咱们只须要设计一个功能,让它能够在数据发生赋值操做的时候去通知一下观察者就能够了。咱们都知道在Python当中,赋值操做是没办法直接感知的,可是类当中的成员发生变化的时候,咱们是能够经过@property装饰器来进行修饰的。优化

因此咱们就利用这一点来实现数据这个类,若是你们熟悉@property注解的话,也很是简单。url

class Data(Subject):

    def __init__(self, name=''):
        Subject.__init__(self)
        self.name = name
        self._data = 0

    @property
    def data(self):
        return self._data

    @data.setter
    def data(self, data):
        self._data = data
        # 关键
        self.notify()

你们看到了data这个方法当中的self.notify了吗?这个就是通知函数,因此就是当Data这个类当中的data成员发生变化的时候,咱们执行通知操做,去通知观察者执行。spa

管理观察者

如今咱们观察者实现好了,数据类也有了,剩下的就是把这二者连通起来了。咱们固然也能够简单粗暴地用代码实现,可是比较好的作法是对数据和观察者之间的联系作一个简单的管理。由于可能不一样的数据须要的观察者不同,咱们并不能简单粗暴地一律而论。线程

其实管理观察者也不须要太复杂,只须要用面向对象的思路对list进行一个简单的封装便可。设计

class Subject:

    def __init__(self):
        self._observer = []

    def attach(self, observer):
        if observer not in self._observer:
            self._observer.append(observer)

    def detach(self, observer):
        try:
            self._observer.remove(observer)
        except ValueError:
            pass

    def notify(self, modifier=None):
        for observer in self._observer:
            if modifier != observer:
                observer.update(self)

attach表示关联,也就是给数据关联上观察者,detach表示解除关联,notify天然就是通知了。其实也就是用一个循环遍历一下全部的观察者,而后执行一下对应的update函数就能够了。

这里为了简化逻辑,咱们把Subject类作成了Data类的父类。这样某种程度上至关于解耦了观察者和数据,咱们之后不管是对哪部分逻辑进行修改或者是优化都不会影响另外两方。整个代码不过50行,能够说是很是简便了,不只是Python,对于其余支出多态的语言来讲,这个设计模式也是一样适用的。

到这里关于观察者模式就介绍完了,今天的文章就到这里。衷心祝愿你们天天都有所收获。若是还喜欢今天的内容的话,请来一个三连支持吧~(点赞、关注、转发

相关文章
相关标签/搜索