前言

观察者模式属于行为型模式,也称为发布订阅模式,应用较广。

例如:微信用户可以关注某1个微信公众号,当该微信公众号发布了新的内容,关注该微信号的微信用户们,将立刻接收到该微信号推送的新消息。

一、观察者/发布-订阅模式

观察者模式又称为发布-订阅模式。

1.概念

观察者模式又称发布订阅模式描述了:对象之间1对多的依赖关系,其中多个观察者角色依赖1个发布者角色。

一旦1个发布者对象的状态发生改变,所有依赖该发布者对象的观察者/订阅者都会自动地收到通知、得到更新

2.角色

  • 抽象主题(Subject)
  • 具体主题(ConcreteSubject)-----发布者
  • 抽象观察者(Observer)
  • 具体观察者(ConcreateObserver)-----订阅/观察者

3.关注点

当1个发布者的状态发生时,依赖该发布者的订阅者都会被自动更新,而不是在高层代码(Client)中判断当前发布者有哪些订阅者,然后进行手动更新;

发布者和订阅者之间的关系描述应该是松耦合的,订阅者可以订阅发布者也可以取消订阅

4.优点

发布者和观察者之间的抽象耦合最小

发布者和观察者之间支持广播通信

5.适用场景

当1个抽象模型有两方面,其中1个方面依赖于另1个方面。将这2者封装在独立对象中以使它们可以各自独立地改变和复用;

当对1个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变;

当1个对象必须通知其它对象,而它又不能假定其它对象是谁,换言之,你不希望这些对象之间是紧密耦合的;

6.实现代码

from abc import ABC, abstractmethod


# 根据设计模式依赖倒置原则:首先定义2个约束订阅者和发布者的接口即和Publisher接口和Observer接口

# 发布者接口     ----抽象发布者
class Publisher(ABC):
    # 使用列表存储订阅了该公众号的订阅者
    def __init__(self):
        self.observers = []

    # 订阅
    def attach(self, observer_obj):
        self.observers.append(observer_obj)

    # 取消订阅
    def detach(self, observer_obj):
        self.observers.remove(observer_obj)

    # 通知所有关注了当前发布者的订阅者们
    def notice(self):
        for current_observer_obj in self.observers:
            current_observer_obj.update(self)


# 观察/订阅者接口  ----抽象订阅者
class Observer(ABC):
    # 观察者更新消息
    @abstractmethod
    def update(self, publisher_obj):
        pass


# 具体发布者:继承发布者接口
class StaffPublisher(Publisher):
    def __init__(self, company_info=None):
        super().__init__()
        self.__company_info = company_info

    # 查看消息:staff_publisher_obj.company_info执行
    @property
    def company_info(self):
        return self.__company_info

    # 发布者发布消息:先更新自己,再触发订阅了该发布者的观察者们更新
    @company_info.setter  # staff_publisher_obj.company_info = "news"时执行
    def company_info(self, company_info):
        self.__company_info = company_info
        self.notice()


# 具体订阅者继承观察/订阅者接口
class StaffObserver(Observer):
    def __init__(self):
        # 维护具体订阅者自己的消息
        self.company_info = None

    # 由发布者触发订阅了该发布者的观察者们更新
    def update(self, publisher_obj):
        # 订阅者更新自己的消息=发布者最新发布的消息
        self.company_info = publisher_obj.company_info


# 高层代码(Client)
staff_publisher = StaffPublisher("初始化公司消息")
staff_observer1 = StaffObserver()
staff_observer2 = StaffObserver()
# 通过发布者attach/detach()方法的建立松耦合的绑定关系
staff_publisher.attach(staff_observer1)
staff_publisher.attach(staff_observer2)
# 1个发布者-发布消息
staff_publisher.company_info = "公司放假了"
# 所有订阅者-查看消息
print("staff_observer1", staff_observer1.company_info)
print("staff_observer2", staff_observer2.company_info)
# 1个发布者-再发布1条消息
staff_publisher.detach(staff_observer1)
staff_publisher.company_info = "上一条公司放假消息系安全演练,请各位忽略!"
# 所有订阅者-再查看消息
print("staff_observer1", staff_observer1.company_info)
print("staff_observer2", staff_observer2.company_info)

 

 

 

 

参考

posted on 2024-02-17 21:56  Martin8866  阅读(10)  评论(0编辑  收藏  举报