观察者模式(Observer Pattern):对象间的联动通知机制
观察者模式是行为型设计模式的一种,核心思想是定义对象间的一对多依赖关系:当一个对象(目标)的状态发生改变时,所有依赖它的对象(观察者)会自动收到通知并更新。这种模式就像 “订阅 - 发布” 系统 —— 订阅者(观察者)关注发布者(目标),当发布者有新内容时,所有订阅者都会收到推送,核心是 “状态联动,自动更新”。
观察者模式的核心结构
观察者模式通过四个核心角色实现对象间的联动,分工明确且耦合度低:
目标接口 / 类(Subject)
- 定义被观察对象的接口,提供注册、移除观察者及通知所有观察者的方法。
- 示例:
NewsPublisher
(新闻发布者,定义addSubscriber()
、removeSubscriber()
、notifySubscribers()
)。
具体目标(ConcreteSubject)
- 实现目标接口,维护自身状态,当状态改变时调用
notify()
方法通知所有观察者。 - 示例:
TechNewsPublisher
(科技新闻发布者,状态为最新新闻内容)。
观察者接口(Observer)
- 定义观察者的接口,声明接收通知并更新自身的方法(通常名为
update()
)。 - 示例:
Subscriber
(订阅者,定义update(String news)
方法)。
具体观察者(ConcreteObserver)
- 实现观察者接口,在收到通知时执行具体的更新逻辑,通常会保存对目标的引用以获取最新状态。
- 示例:
EmailSubscriber
(邮件订阅者,收到新闻后发送邮件)、AppSubscriber
(APP 订阅者,收到新闻后推送通知)。
代码实现示例
以 “新闻订阅系统” 为例,展示观察者模式的实现:新闻发布者(目标)发布新闻时,所有订阅者(观察者)会自动收到通知。
1. 目标接口与具体目标
1 | // 1. 目标接口:新闻发布者 |
2. 观察者接口与具体观察者
1 | // 3. 观察者接口:订阅者 |
3. 客户端使用
1 | public class ObserverDemo { |
观察者模式的核心优势
- 松耦合的联动关系
目标与观察者之间通过接口通信,互不依赖具体实现:- 目标无需知道观察者的具体类型,只需调用其
update()
方法。 - 观察者可随时新增或移除,不影响目标的逻辑。
- 目标无需知道观察者的具体类型,只需调用其
- 自动通知与更新
目标状态改变时,所有观察者会被自动通知并更新,无需手动触发,确保状态一致性。 - 支持一对多通信
一个目标可对应多个观察者(如新闻发布者可被无数用户订阅),适合广播场景。 - 符合开闭原则
新增观察者时无需修改目标代码,只需实现观察者接口并注册,扩展性强。
适用场景
- 状态联动场景
当一个对象的状态变化需要联动更新其他多个对象时(如:- GUI 界面:按钮点击后,多个组件(文本框、列表)联动更新。
- 股票系统:股价变动时,所有关注该股票的用户收到提醒。
- 事件监听:如鼠标点击、键盘输入等事件的处理。
- 订阅 - 发布系统
如 RSS 订阅、邮件列表、消息队列(MQ)的发布 - 订阅模式(本质是观察者模式的扩展)。 - 事件驱动架构
系统核心模块作为目标,其他模块作为观察者监听核心事件(如日志系统、监控系统)。
优缺点分析
优点
- 低耦合:目标与观察者通过接口交互,减少直接依赖。
- 高灵活性:观察者可动态添加 / 移除,适应变化。
- 自动化:状态变化时自动通知,减少手动协调成本。
缺点
- 通知顺序不确定:目标对观察者的通知顺序不保证,若观察者间有依赖关系可能导致问题。
- 资源消耗:若观察者过多或更新逻辑复杂,可能导致通知效率降低。
- 循环依赖风险:若观察者更新时又触发目标状态改变,可能导致无限循环。
经典应用案例
- Java 的
java.util.Observable
与Observer
Java 内置了观察者模式的实现:Observable
是目标类,Observer
是观察者接口,通过notifyObservers()
触发更新。(注:Java 9 后已标记为过时,推荐使用java.beans
包或第三方库)。 - Spring 的事件机制
Spring 的ApplicationEvent
(事件,类似目标状态)和ApplicationListener
(监听器,类似观察者)实现了观察者模式,用于组件间的解耦通信(如ContextRefreshedEvent
通知容器刷新完成)。 - GUI 框架的事件监听
如 Swing 的ActionListener
(按钮点击事件的观察者)、MouseListener
(鼠标事件的观察者),按钮作为目标,点击时通知所有监听器。 - 消息队列(MQ)的发布 - 订阅模式
如 RabbitMQ 的fanout
交换机,生产者(目标)发送消息后,所有绑定该交换机的队列(观察者)都会收到消息,是分布式系统中的观察者模式扩展。
总结
观察者模式通过 “目标 - 观察者” 的一对多关系,实现了对象间的低耦合联动,核心是 “状态变化自动通知,观察者被动更新”。它特别适合需要联动更新的场景,如事件驱动、订阅系统等。使用时需注意控制观察者数量和更新逻辑复杂度,避免效率问题
v1.3.10