Skip to content

设计模式之观察者模式

知行合一。

Author:李东阳

1、什么是观察者模式

内容

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。又称“发布-订阅”模式。

角色

  • 抽象主题(Subject)

  • 具体主题(Concrete Subject)

  • 抽象观察者(Observer)

  • 具体观察者(Concrete Observer)

2、观察者模式的具体实现

其实。观察者模式很容易理解,也很常见。就比如说,微信公众号、抖音等等都可以算是观察者模式。其本质就是,主要发布者的消息一改变,那么观察者们会立即自动更新其消息。

这玩意还是挺好玩的。

直接看代码实现:

from abc import ABCMeta, abstractmethod


# 抽象观察者
class Observer(metaclass=ABCMeta):
    @abstractmethod
    def update(self, notice):  # notice为这个订阅者所订阅的对象,即发布者
        pass


# 抽象发布者
class Notice:
    def __init__(self):
        self.obersers = []  # 这个列表用来保存该发布者的观察者

    def add(self, obs):  # 添加观察者
        self.obersers.append(obs)  # 存入观察者对象

    def remover(self, obs):  # 删除观察者
        self.obersers.remove(obs)  # 删除观察者对象

    def notify(self):  # 发布信息
        for obs in self.obersers:
            obs.update(self)  # 将发布者本身传入


# 具体发布者
class StaffNotice(Notice):
    def __init__(self, company_info=None):
        super().__init__()
        self.__company_info = company_info  # 公司的公告信息

    @property
    def company_info(self):
        return self.__company_info  # 负责读

    @company_info.setter  # 这里可以去具体了解一下 主要的效果就是,只要这个company_info被修改就执行这个函数
    def company_info(self, info):  # 这个参数是要更新的info
        self.__company_info = info
        self.notify()  # 推送新的info


# 具体观察者
class Staff(Observer):
    def __init__(self):
        self.company_info = None  # 这是员工自己订阅到的信息

    def update(self, notice):
        self.company_info = notice.company_info  # 将观察者的company_info更新


t = Staff()  # 创建俩个订阅者
t2 = Staff()
s = StaffNotice()  # 创建一个发布者
s.add(t)  # 两个订阅者读订阅这个发布者
s.add(t2)
print(t.company_info)  
s.company_info = '公司明天放假!'  # 我们一修改发布者的info,订阅者的消息立即更新,从而实现了消息的订阅
print(t.company_info)
print(t2.company_info)

# 输出
# None
# 公司明天放假!
# 公司明天放假!

细细品一品

3、总结

优点

  • 目标和观察者之间的抽象耦合很小

  • 支持广播通信

  • 可以在无需对主题或观察者进行任何修改的情况下,高效地发送数据到其他对象。

  • 可以随时添加/删除观察者。

缺点

  • 观察者接口必须由具体观察者实现,而这涉及继承。无法进行组合,因为观察者接口可以实例化。

  • 如何实现不当的华,观察者可能会增加复杂性,并且导致性能降低。

  • 通知可能不可靠,并且导致竞争条件或不一致。