设计模式Python实现-观察者模式
观察者模式(发布-订阅模式 Publish Subscribe Pattern):定义了一种一对多的关系,让多个观察对象同时监听一个主题对象,当主题对象状态发生变化时会通知所有观察者,是它们能够自动更新自己,是一种行为设计模式。
观察者模式的结构
1,Publisher 会向其他对象发送值得关注的事件notifySubscribers。事件会在发布者自身状态改变或执行特定行为后发生。发布者中包含一个允许新订阅者加入subscribe和当前订阅者离开列表unsubscribe的订阅构架。
2,当新事件发生时,发送者会遍历订阅列表并调用每个订阅者对象的通知方法。该方法是在订阅者接口中声明的。
3,Subscriber 接口声明了通知接口。在绝大多数情况下,该接口仅包含一个update方法。该方法可以拥有多个参数,使发布者能在更新时传递事件的详细信息。
4,Concrete Subscriber 具体订阅者,可以执行一些操作来回应发布者的通知。所有具体订阅者类都实现了同样的接口,发布者不与具体类相耦合。
5,订阅者通常需要一些上下文信息来正确地处理更新。因此,发布者通常会将一些上下文数据作为通知方法的参数进行传递。发布者也可将自身作为参数进行传递,使订阅者直接获取所需的数据。
6,Client 会分别创建发布者和订阅者对象,然后为订阅者注册发布者更新。
观察者代码
1 from __future__ import annotations 2 from abc import ABC, abstractmethod 3 from random import randrange 4 from typing import List 5 6 7 class Subject(ABC): 8 """ 9 声明一组用于管理订阅者的方法 10 """ 11 12 @abstractmethod 13 def attach(self, observer: Observer) -> None: 14 """ 15 添加观察者到subject. 16 """ 17 pass 18 19 @abstractmethod 20 def detach(self, observer: Observer) -> None: 21 """ 22 从subject删除观察者. 23 """ 24 pass 25 26 @abstractmethod 27 def notify(self) -> None: 28 """ 29 通知观察者事件的发生. 30 """ 31 pass 32 33 34 class ConcreteSubject(Subject): 35 """ 36 Subject有一些状态,状态变更需要通知观察者 37 """ 38 # Subject的状态,所有的订阅者都要有, 39 _state: int = None 40 41 # 订阅用户列表 42 _observers: List[Observer] = [] 43 44 def attach(self, observer: Observer) -> None: 45 print("Subject: Attached an observer.") 46 self._observers.append(observer) 47 48 def detach(self, observer: Observer) -> None: 49 self._observers.remove(observer) 50 51 # 通知所有订阅者 52 def notify(self) -> None: 53 """ 54 通知接口,触发了所有的订阅用户的update方法 55 """ 56 57 print("Subject: Notifying observers...") 58 for observer in self._observers: 59 observer.update(self) 60 61 def some_business_logic(self) -> None: 62 """ 63 一些业务逻辑块,处理业务逻辑后,也可能会触发状态的变更,需要调用notify通知所有订阅者, 64 """ 65 66 print("\nSubject: state change") 67 self._state = randrange(0, 10) 68 69 print(f"Subject: My state has changed to: {self._state}") 70 self.notify() 71 72 73 class Observer(ABC): 74 """ 75 订阅者声明对象使用的update. 76 """ 77 78 @abstractmethod 79 def update(self, subject: Subject) -> None: 80 """ 81 接收到状态变更. 82 """ 83 pass 84 85 86 """ 87 具体订阅者,对状态的变更做出具体反应 88 """ 89 90 91 class ConcreteObserverA(Observer): 92 def update(self, subject: Subject) -> None: 93 if subject._state < 3: 94 print("ConcreteObserverA: Reacted to the event") 95 96 97 class ConcreteObserverB(Observer): 98 def update(self, subject: Subject) -> None: 99 if subject._state == 0 or subject._state >= 2: 100 print("ConcreteObserverB: Reacted to the event") 101 102 103 if __name__ == "__main__": 104 # The client code. 105 106 subject = ConcreteSubject() 107 108 observer_a = ConcreteObserverA() 109 subject.attach(observer_a) 110 111 observer_b = ConcreteObserverB() 112 subject.attach(observer_b) 113 114 subject.some_business_logic() 115 subject.some_business_logic() 116 117 subject.detach(observer_a) 118 119 subject.some_business_logic()
适用场景:
1,当一个对象状态的改变需要改变其他对象,或实际对象是事先未知的或动态变化的时,可使用观察者模式。
2,当应用中的一些对象必须观察其他对象时,可使用该模式。
优点:
符合开闭原则,不用修改发布者代码就能引入新的订阅者类。
可以在运行时建立对象之间的联系。
缺点:
订阅者的通知顺序是随机的
作者:Andy
出处:http://www.cnblogs.com/onepiece-andy/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。