<<返回python首页 python

《Python 应用案例》

Python设计模式:观察者模式

Python设计模式 观察者

观察者模式也叫发布订阅模式, 定义了对象之间一对多依赖,当一个对象改变状态时,这个对象的所有依赖者都会收到通知并按照自己的方式进行更新。观察者模式是对象的行为模式,又叫发布-订阅(pubish/subscribe)模式,模型-视图(Model/View模式),源-监听器(Source/Listener)模式或从属者(Dependents)模式。

角色:

抽象主题,具体主题(发布者), 抽象观察者,具体观察者(订阅者)

适用场景:

当一个抽象模型有两个方面,其中一个方面依赖于另一个方面.将两者封装在独立的对象中以使它们各自独立的改变和复用

当一个对象的改变需要同时改变其他对象,而且不知道具体有多少对象以待改变

当一个对象必须通知其他对象,而又不知道其他对象是谁,即这些对象之间是解耦的

优点:

目标与观察者之间的耦合最小

推模型和拉模型:

观察者模式根据其侧重的功能还可以分为推模型和拉模型。

推模型:被观察者对象向观察者推送主题的详细信息,不管观察者是否需要,推送的信息通常是主题对象的全部或部分数据。一般这种模型的实现中,会把被观察者对象中的全部或部分信息通过 update 的参数传递给观察者 [update(Object obj) ,通过 obj 参数传递]。

拉模型:被观察者在通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,由观察者主动到被观察者对象中获取,相当于是观察者从被观察者对象中拉数据。一般这种模型的实现中,会把被观察者对象自身通过 update 方法传递给观察者 [update(Observable observable ),通过 observable 参数传递 ],这样在观察者需要获取数据的时候,就可以通过这个引用来获取了。

缺点:

多个观察者之间互不知道对方的存在,因此一个观察者对主题的修改可能造成错误的更新

好, 概念说完来实际场景,以我目前公司业务为背景,产品上线后经常会收到用户反馈bug。那么通常由运营同事收集bug-》开发修复bug-》测试验证bug-》运维发布新版本到线上

示例1:

class OBperson():
    '抽象观察者'
    def updata(self):
        pass

class TestOB(OBperson):
    '具体观察者'
    def updata(self):
        print('I am tester, Verification bug')

class Devob(OBperson):
    '具体观察者'
    def updata(self):
        print('i am developing , Fix bug')

class Announcerob(OBperson):
    '具体观察者'
    def updata(self):
        print('i am announcer, release new version')

class OBperation():
    '具体发布者'
    def __init__(self):
        self.__observers = []

    def collect_bug(self):
        print('Number of bugs collected : ')
        self.notifyObserver()

    def addOBserver(self, observer):
        self.__observers.append(observer)

    def removeOBserver(self, observer):
        self.__observers.remove(observer)

    def notifyObserver(self):
        for ob in self.__observers:
            ob.updata()

if __name__ == '__main__':
    p = OBperation()
    p.addOBserver(Devob())
    p.addOBserver(TestOB())
    p.addOBserver(Announcerob())
    p.collect_bug()

示例2:

举个现实生活的例子, 职员们趁老板不在,都在玩着自己的东西,同时观察着前台小姐姐,前台小姐姐在老板回来的时候,发布通知让各同事回到工作状态。

① 职员们

都是观察者,时刻观察着前台小姐姐,等她提前通知老板的到来。

# 看股票的职员
class StockClerk:
    def __init__(self, name):
        self.name = name

    def close_stock_software(self):
        print(f"{self.name} 关闭了股票软件,并开始办公")


# 睡着的职员
class SleepingClerk:
    def __init__(self, name):
        self.name = name

    def open_word(self):
        print(f"{self.name} 打开了word,并开始办公")

② 前台小姐姐

给各个观察者通风报信的人。

class Receptionist:
    actions = []

    @classmethod
    def attach(cls, action):
        cls.actions.append(action)

    @classmethod
    def notify(cls):
        print("老板回来了,各同事行动...")
        for actioin in cls.actions:
            actioin()

③ 大家偷懒的时候,老板突然回来,前台小姐姐通知大家回到工作状态

# 实例化职员
c1 = StockClerk('Chris')
c2 = SleepingClerk('Ryan')

# 告诉前台小姐姐如何通知
Receptionist.attach(c1.close_stock_software)
Receptionist.attach(c2.open_word)

# 前台小姐姐发布通知
Receptionist.notify()

设计要点:

被观察者至少需要有三个方法:添加监听者, 移除监听者, 通知OBserver的方法,观察者至少要有一个方法:更新方法,更新当前内容,并作出相应处理。

移动端设备除iPad Pro外,其它移动设备仅能阅读基础的文本文字。
建议使用PC或笔记本电脑,浏览器使用Chrome或FireFox进行浏览,以开启左侧互动实验区来提升学习效率,推荐使用的分辨率为1920x1080或更高。
我们坚信最好的学习是参与其中这一理念,并致力成为中文互联网上体验更好的学练一体的IT技术学习交流平台。
您可加QQ群:575806994,一起学习交流技术,反馈网站使用中遇到问题。
内容、课程、广告等相关合作请扫描右侧二维码添加好友。

狐狸教程 Copyright 2021

进入全屏