伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

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

来源:本站原创 浏览:143次 时间:2021-08-28

大家好,我们今天来了解一个新的设计模式——观察者模式。

观察者模式的思路很简单,它被广泛地用在各种数据监控上。很多时候我们希望监听某个数据的变化,希望一旦获悉它的变化之后立即采取一些举措。按照常规的操作,我们需要开启额外的线程来进行监听。但是开启线程一则非常麻烦,二则需要带来额外的开销,我们今天介绍的观察者模式就可以在无需多余开销的基础上完成这个功能。

观察者

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

首先,我们来实现两个监听器。也就是当数据发生变化之后会触发这两个监听器。在这个设计模式当中,监听器被命名为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.dataclass 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注解的话,也非常简单。

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成员发生变化的时候,我们执行通知操作,去通知观察者执行。

管理观察者

现在我们观察者实现好了,数据类也有了,剩下的就是把这两者连通起来了。我们当然也可以简单粗暴地用代码实现,但是比较好的做法是对数据和观察者之间的联系做一个简单的管理。因为可能不同的数据需要的观察者不一样,我们并不能简单粗暴地一概而论。

其实管理观察者也不需要太复杂,只需要用面向对象的思路对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,对于其他支出多态的语言来说,这个设计模式也是同样适用的。

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

  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net