观察者模式
观察者模式定义了一种一对多的订阅关系,当一个对象的状态发生变化时,所有订阅它的对象都会得到通知。
结构
观察者模式示意图
观察者模式中,发布者(Publisher)对象维护了一个订阅者列表,并提供了订阅、退订和通知订阅者的方法。发布者对象在特定事件发生时会通知所有订阅者对象。具体订阅者对象通过实现订阅者(Subscriber)接口来接收通知。
备注
事实上,也可以将业务代码与发布者解耦,使得发布者仅负责通知订阅者,而不关心具体的业务逻辑。这样可以使得发布者对象更加通用,更易于复用。
信息
不难注意到观察者模式和 中介者模式 的相似之处。两者都是用于解耦组件之间的通信,但存在以下不同:
- 中介者的主要目标是消除一系列系统组件之间的相互依赖。观察者的目标是在对象之间建立动态的单向连接, 使得部分对象可作为其他对象的附属发挥作用。
- 中介者模式可以基于观察者模式实现,但是也可采用其他方式来实现。
- 中介者常常是中心化的,而观察者模式中的发布者可以是分布式、去中心化的。
应用场景
- 当一个对象状态的改变需要动态改变其他对象时
优缺点
优点
- 开闭原则:你无需修改发布者代码就能引入新的订阅者类。
- 在运行时建立对象之间的动态联系。
缺点
- 观察者模式不保证通知的顺序。
代码示例
下面通过一个简单的新闻订阅系统展示了观察者模式的实现。
NewsAgency
是发布者(也叫主题或可观察者),它维护一个订阅者列表,并有一个 _state
属性来存储最新的新闻。当 publish_news
方法被调用时,它的状态会改变,然后它会调用 notify
方法来通知所有已注册的观察者。
Observer
是一个接口,定义了所有具体观察者必须实现的 update
方法。NewsReader
是一个具体的观察者,它实现了 update
方法,以便在收到发布者的通知时做出反应(在这里是打印新闻)。
客户端代码创建了发布者和多个观察者,并将观察者附加到发布者上。当发布者发布新消息时,所有附加的观察者都会自动收到通知并更新自己的状态,而发布者和观察者之间没有紧密的耦合关系。