前言
观察者模式属于行为型模式,也称为发布订阅模式,应用较广。
例如:微信用户可以关注某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)
参考