• python 设计模式 观察者模式(发布订阅模式)


    发布订阅模式

    观察者模式应用比较广泛,又被称为“发布-订阅”模式。它用来定义对象间一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都得到通知并被自动更新。

    问题1

    例子为什么要使用“ @property 与 @*.setter ”装饰器语法?

    出于安全与调用者方便的原因
    1.由于为了隐藏发布者消息被篡改,所以设置成立私有属性__
    2.设置私有属性后,就必须单独写一个函数来调用,一个属性却需要使用函数的调用方式,会让调用者迷惑。要使用"@property"装饰器语法
    3.这个属性,有时会需要调用者重新赋值,要使用"@*.setter"装饰器语法

    以上的内容也是为了演示,在订阅者名单中,删除某订阅者名字后,某订阅者会不会收到新消息。

    from abc import ABCMeta, abstractmethod
    
    
    # 抽象的订阅者
    class Observer(metaclass=ABCMeta):
        @abstractmethod
        def update(self, notice):
            pass
    
    
    # 抽象的发布者:可以是接口,子类不需要实现,所以不需要定义抽象方法!
    class Notice:
        def __init__(self):
            self.observers = []
    
        def attach(self, obs):
            # 添加 订阅者名单
            self.observers.append(obs)
    
        def detach(self, obs):
            # 删除 订阅者名单
            self.observers.remove(obs)
    
        def notify(self):
            # 遍历订阅者名单
            for obs in self.observers:
                # 使用订阅者的方法,把发布者作为参数输入
                obs.update(self)
    
    
    # 具体的发布者
    class StaffNotice(Notice):
        def __init__(self, company_info):
            super().__init__()  # 调用父类对象声明observers属性
            # 设置了私有属性
            self.__company_info = company_info
    
        # @property 与 @*.setter 可以配合使用
    
        # 既要保护类的封装特性,又要让开发者可以使用“对象.属性”的方式操作操作类属性,
        # 通过 @property 装饰器,可以直接通过方法名来访问方法,不需要在方法名后添加一对“()”小括号。
        @property
        def company_info(self):
            # 直接返回 __company_info
            return self.__company_info
    
        # 两个同名函数, 当company_info这个"属性"被赋值时,该函数会被执行 (预处理)
        @company_info.setter
        def company_info(self, info):
            # 更新 __company_info
            self.__company_info = info
            # 调用发布者的方法
            self.notify()
    
    
    # 具体的订阅者
    class Staff(Observer):
        def __init__(self):
            self.company_info = None
    
        def update(self, notice):
            # 输入参数.调用发布者的方法 赋值给 订阅者(自己)
            self.company_info = notice.company_info
    
    
    # 实例化 发布者
    staff_notice = StaffNotice('初始化公司信息')
    
    # 实例化 订阅者
    staff1 = Staff()
    staff2 = Staff()
    
    # 添加订阅
    staff_notice.attach(staff1)
    staff_notice.attach(staff2)
    # print(staff1.company_info) None
    # print(staff2.company_info) None
    
    # 当company_info这个"属性"被赋值时, 会触发"预处理"
    # 订阅者 会接收 发布者 的消息
    staff_notice.company_info = '假期放假通知!'
    print(staff1.company_info)
    print(staff2.company_info)
    
    # 删除 订阅者 staff2
    staff_notice.detach(staff2)
    
    # 重新 发布订阅
    staff_notice.company_info = '明天开会!'
    # staff1 会接收到新的消息
    print(staff1.company_info)
    # staff2 不会接收到新的消息
    print(staff2.company_info)
    """
    假期放假通知!
    假期放假通知!
    明天开会!
    假期放假通知!
    """
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
  • 相关阅读:
    【Linux】进程控制 (万字详解)—— 进程创建 | 进程退出 | 进程等待 | 程序替换 | 实现简易shell
    16S全长测序揭示绿头虻肠道微生物及共生细菌
    面试问题梳理:项目中防止配置中的密码泄露-Jasypt
    体育竞技分析
    评价——秩和比综合评价
    Linux——centos7.4磁盘空间调整分配
    [云原生k8s] k8s的CA证书创建和使用及ETCD集群
    Pandas基础入门知识点总结
    软件测试中功能测试流程
    树型结构和二叉树的概念及特性
  • 原文地址:https://blog.csdn.net/qq_42102546/article/details/126824338