• 内容:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。观察者模式又称 “发布—-订阅”模式
    • 角色:
      • 抽象主题(Subject)
      • 具体主题(ConcreteSubject) —- 发布者
      • 抽象观察者 (Observer)
      • 具体观察者(ConcreteObserver) —-订阅者

    image.png

    1. from abc import ABCMeta, abstractmethod
    2. class Observer(metaclass=ABCMeta):
    3. @abstractmethod
    4. def update(self, notice):
    5. pass
    6. class Notice:
    7. def __init__(self):
    8. self.observers = []
    9. def attach(self, obs):
    10. self.observers.append(obs)
    11. def detach(self, obs):
    12. self.observers.remove(obs)
    13. def notify(self):
    14. for obj in self.observers:
    15. obj.update(self)
    16. class ManagerNotice(Notice):
    17. def __init__(self, company_info=None):
    18. super().__init__()
    19. self.__company_info = company_info
    20. @property
    21. def company_info(self):
    22. return self.__company_info
    23. @company_info.setter
    24. def company_info(self, info):
    25. self.__company_info = info
    26. self.notify()
    27. class Manager(Observer):
    28. def __init__(self):
    29. self.company_info = None
    30. def update(self, noti):
    31. self.company_info = noti.company_info
    32. notice = ManagerNotice()
    33. alex = Manager()
    34. wusir = Manager()
    35. #print(alex.company_info)
    36. #print(wusir.company_info)
    37. notice.attach(alex)
    38. notice.attach(wusir)
    39. #
    40. notice.company_info="公司运行良好"
    41. #
    42. #print(alex.company_info)
    43. #print(wusir.company_info)
    44. notice.company_info="公司将要上市"
    45. #print(alex.company_info)
    46. #print(wusir.company_info)
    47. #
    48. notice.detach(wusir)
    49. #
    50. notice.company_info="公司要破产了,赶快跑路"
    51. print(alex.company_info)
    52. print(wusir.company_info)
    • 适用场景:
      • 当一个抽象模型有两方面,其中一个方面依赖于另一个方面。将这两者封装在独立对象中以使它们可以各自独立改变和复用。
      • 当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。
      • 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧密耦合的。
    • 优点:
      • 目标和观察者之间的抽象耦合最小
      • 支持广播通信
    • 缺点:
      • 多个观察者之间互不知道对方存在,因此一个观察者对主题的修改可能造成错误的更新。