观察者模式与发布订阅区别
观察者模式(Observer Pattern) 和 发布-订阅模式(Pub/Sub Pattern) 经常被混用,但它们在耦合度、通信方式、使用场景上是有区别的。下面从多个维度来对比说明。
一句话总结
观察者模式是“直接通知”,发布-订阅模式是“通过中介分发”。
一、观察者模式(Observer Pattern)
核心思想
对象之间存在一对多依赖关系,当目标对象(Subject)状态发生变化时,直接通知所有观察者(Observer)。
结构
Subject(被观察者)
├── registerObserver()
├── removeObserver()
└── notifyObservers()
Observer(观察者)
└── update()
通信方式
- 直接调用
- 被观察者知道观察者是谁(持有观察者引用)
特点
✅ 结构清晰
✅ 实现简单
❌ 被观察者和观察者强耦合
示例
class Subject {
List observers = new ArrayList<>();
void notifyObservers() {
for (Observer o : observers) {
o.update();
}
}
}
使用场景
- GUI 事件监听
- MVC 架构
- 状态变化同步
二、发布-订阅模式(Pub/Sub Pattern)
核心思想
发布者和订阅者互不认识,通过**消息中间件(事件总线)**进行通信。
结构
Publisher → Event Bus → Subscriber
通信方式
- 通过事件通道或消息队列
- 发布者不知道谁订阅了事件
特点
✅ 解耦彻底
✅ 易于扩展
✅ 支持异步、跨模块 / 跨系统
❌ 结构复杂
示例(概念)
eventBus.on('order_created', callback);
eventBus.emit('order_created', data);
使用场景
- 前端事件总线(Vue / React)
- 消息队列(Kafka / RabbitMQ)
- 微服务通信
- 跨组件通信
三、核心区别对照表
| 对比项 | 观察者模式 | 发布-订阅模式 |
|---|---|---|
| 是否有中介 | ❌ 无 | ✅ 有(事件总线 / MQ) |
| 耦合度 | 强耦合 | 松耦合 |
| 谁通知谁 | 被观察者 → 观察者 | 发布者 → 中介 → 订阅者 |
| 角色感知 | 互相知道 | 互不知道 |
| 是否支持异步 | 通常是同步 | 通常支持异步 |
| 典型应用 | UI、MVC | 消息队列、前端事件 |
四、关系与误区
发布-订阅是观察者模式的“升级版”或“变种”
- 观察者模式:面向对象级
- 发布-订阅模式:系统级 / 架构级
❌ 常见误区:
“Vue 的
$emit/$on是观察者模式”
✅ 更准确的说法:
Vue 的事件机制是发布-订阅模式
五、面试一句话回答(推荐)
观察者模式中,被观察者直接通知观察者,两者耦合较紧;
发布-订阅模式通过事件通道解耦发布者和订阅者,适合更大规模或异步通信。
如果你愿意,我可以:
- 用 Java / JS / Python 写一个对比示例
- 从 Vue / React / 后端架构 角度再讲一遍
- 帮你整理成 面试标准答案版