观察者模式应用比较广泛,又被称为“发布-订阅”模式。它用来定义对象间一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都得到通知并被自动更新。观察者模式的角色有:抽象主题、具体主题(发布者)、抽象观察者和具体观察者(订阅者)。
from abc import ABCMeta, abstractmethod # 抽象的订阅者 class Observer(metaclass=ABCMeta): @abstractmethod def updata(self, notice): """ :param notice: Notice类的对象 :return: """ pass # 抽象的发布者:可以是接口,子类不需要实现,所以不需要定义抽象方法! class Notice(object): def __init__(self): self.observers = [] def attach(self, obs): self.observers.append(obs) def detach(self, obs): self.observers.remove(obs) def notice(self): """ 推送 :return: """ for obs in self.observers: obs.updata(self) # 具体的发布者 class StaffNotice(Notice): def __init__(self, company_info): super().__init__() # 调用父类对象声明observers属性 self.__company_info = company_info @property def company_info(self, ): return self.__company_info @company_info.setter def company_info(self, info): self.__company_info = info self.notice() # 具体的订阅者 class Staff(Observer): def __init__(self): self.company_info = None def updata(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 staff_notice.company_info = '假期放假通知!' print(staff1.company_info) print(staff2.company_info) staff_notice.detach(staff2) staff_notice.company_info = '明天开会!' print(staff1.company_info) print(staff2.company_info) """ 假期放假通知! 假期放假通知! 明天开会! 假期放假通知! """
使用场景:当一个抽象模型有两个方面,其中一个方面依赖另一个方面。将这两者封装在独立对象中以使它们可以各自独立地改变和复用;当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象待改变;当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧耦合的。优点:目标和观察者之间的抽象耦合最小;支持广播通信。