IOTXING

记录技术学习之路

0%

python设计模式实现之观察者模式

观察者模式

模拟场景

一个气象站,能够提供例如温度,湿度,风向等天气数据。有几家公司都需要依赖于这个气象站提供的数据来提供自己的服务,比如公司a利用温度,去推送给 用户一些穿衣的建议,公司b根据风向等,为渔民提供出海的建议等。由于他们都需要一直利用气象站的数据,因此需要不停的获取到新的数据。 一般的做法可以是通过定时去请求接口,然后获取到新的数据,但是这样做会增加资源的消耗。比如今天的天气很稳定,半天没有更新了,而公司a还是几秒钟去请求一次接口,这样就会造成一些无谓的消耗 后来经过协商,公司们跟气象站达成了一项协议,在每次气象信息更新的时候,不是由公司们去请求数据,而是有气象站主动推送数据给公司,然后根据每个公司不同的处理方式来完成他们的业务 公司a和公司b通过向气象站进行注册,每次气象站的数据更新的时候都会对两家公司进行通知,然后 两家公司再进行各自的处理 公司c在一开始的时候也是在气象站进行注册,然后在数据更新的时候接受通知,后来觉得别的地方的数据更全,就在气象站取消了注册。之后的每次数据更新,就不会通知到公司c了

详解

观察者模式属于一种设计模式,由观察者与被观察者构成。观察者依赖被观察者做出相应的反应。 被观察者应该提供以下几种方法:

  • 注册
  • 取消注册
  • 通知

观察者需要提供的方法:

  • 注册到被观察者
  • 更新函数

观察者通过调用被观察者的注册函数,注册成为观察者,然后被观察者在数据更新的时候,通过通知函数调用更新函数,对观察者进行更新

代码实现

我主要分为了三个文件,一个是subject类,里面设计了观察者与被观察者类的一些基本信息,然后观察者和被观察者只需要重写一些方法就行。source类,作为被观察者,重写了subject中的函数。object类,作为观察者 Subject

class subject:
    def __init__(self):
        self.observerList = []

    def registerObserver(self, observer):
        pass

    def removeObserver(self, observer):
        pass

    def notiObserver(self, data):
        pass


class observer:
    def update(self, data):
        pass

Source

from subject import subject


class source(subject):
    def notiObserver(self,data):
        for observer in self.observerList:
            observer.update(data)

    def removeObserver(self, observer):
        self.observerList.remove(observer)

    def registerObserver(self, observer):
        self.observerList.append(observer)

    def generateData(self):
        for i in range(10):
            self.notiObserver(i)

observer

from subject import observer
class noti1(observer):
    def __init__(self,observer):
        observer.registerObserver(self)

    def update(self, data):
        print '======noti1======'
        print data

class noti2(observer):
    def __init__(self,observer):
        observer.registerObserver(self)

    def update(self, data):
        print '======noti2======'
        print data

run

from source import  source
from observer import  noti1,noti2


newSource = source()
noti1(newSource)
noti2(newSource)

newSource.generateData()

实际运行效果

======noti1======
0
======noti2======
0
======noti1======
1
======noti2======
1
======noti1======
2
....