观察者模式(发布-订阅模式 Publish Subscribe Pattern):定义了一种一对多的关系,让多个观察对象同时监听一个主题对象,当主题对象状态发生变化时会通知所有观察者,是它们能够自动更新自己,是一种行为设计模式。
观察者模式的结构
1,Publisher 会向其他对象发送值得关注的事件notifySubscribers。事件会在发布者自身状态改变或执行特定行为后发生。发布者中包含一个允许新订阅者加入subscribe和当前订阅者离开列表unsubscribe的订阅构架。
2,当新事件发生时,发送者会遍历订阅列表并调用每个订阅者对象的通知方法。该方法是在订阅者接口中声明的。
3,Subscriber 接口声明了通知接口。在绝大多数情况下,该接口仅包含一个update方法。该方法可以拥有多个参数,使发布者能在更新时传递事件的详细信息。
4,Concrete Subscriber 具体订阅者,可以执行一些操作来回应发布者的通知。所有具体订阅者类都实现了同样的接口,发布者不与具体类相耦合。
5,订阅者通常需要一些上下文信息来正确地处理更新。因此,发布者通常会将一些上下文数据作为通知方法的参数进行传递。发布者也可将自身作为参数进行传递,使订阅者直接获取所需的数据。
6,Client 会分别创建发布者和订阅者对象,然后为订阅者注册发布者更新。
观察者代码
1 from __future__ importannotations2 from abc importABC, abstractmethod3 from random importrandrange4 from typing importList5
6
7 classSubject(ABC):8 """
9 声明一组用于管理订阅者的方法10 """
11
12 @abstractmethod13 def attach(self, observer: Observer) ->None:14 """
15 添加观察者到subject.16 """
17 pass
18
19 @abstractmethod20 def detach(self, observer: Observer) ->None:21 """
22 从subject删除观察者.23 """
24 pass
25
26 @abstractmethod27 def notify(self) ->None:28 """
29 通知观察者事件的发生.30 """
31 pass
32
33
34 classConcreteSubject(Subject):35 """
36 Subject有一些状态,状态变更需要通知观察者37 """
38 #Subject的状态,所有的订阅者都要有,
39 _state: int =None40
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 inself._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 classObserver(ABC):74 """
75 订阅者声明对象使用的update.76 """
77
78 @abstractmethod79 def update(self, subject: Subject) ->None:80 """
81 接收到状态变更.82 """
83 pass
84
85
86 """
87 具体订阅者,对状态的变更做出具体反应88 """
89
90
91 classConcreteObserverA(Observer):92 def update(self, subject: Subject) ->None:93 if subject._state < 3:94 print("ConcreteObserverA: Reacted to the event")95
96
97 classConcreteObserverB(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/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。