如何理解观察者模式
观察者模式(Observer Pattern)是一种行为型设计模式,其核心思想是:
当一个对象的状态发生变化时,自动通知所有依赖它的对象,而无需关心这些对象的具体实现。
一、核心思想(一句话版)
“一对多”的依赖关系:一个主题(Subject)变化,多个观察者(Observer)自动更新。
二、生活中的类比
公众号订阅
- 公众号 = 被观察者(Subject)
- 用户 = 观察者(Observer)
- 用户订阅公众号 → 公众号发新文章 → 所有订阅用户自动收到通知
你不需要一直刷新公众号,只要“关注”了,它更新你就能收到。
三、结构组成
1️⃣ 角色说明
| 角色 | 作用 |
|---|---|
| Subject(主题) | 维护观察者列表,提供注册、移除、通知方法 |
| Observer(观察者接口) | 定义更新接口 |
| ConcreteSubject | 具体主题,状态变化后通知观察者 |
| ConcreteObserver | 具体观察者,实现更新逻辑 |
四、简单示例(Java 风格)
1. 观察者接口
public interface Observer {
void update(String message);
}
2. 主题(被观察者)
import java.util.ArrayList;
import java.util.List;
public class Subject {
private List observers = new ArrayList<>();
private String state;
public void attach(Observer observer) {
observers.add(observer);
}
public void detach(Observer observer) {
observers.remove(observer);
}
public void setState(String state) {
this.state = state;
notifyObservers();
}
private void notifyObservers() {
for (Observer o : observers) {
o.update(state);
}
}
}
3. 具体观察者
public class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + " 收到消息:" + message);
}
}
4. 使用
public class Main {
public static void main(String[] args) {
Subject subject = new Subject();
Observer o1 = new ConcreteObserver("观察者A");
Observer o2 = new ConcreteObserver("观察者B");
subject.attach(o1);
subject.attach(o2);
subject.setState("状态发生变化!");
}
}
五、观察者模式的优点
✅ 解耦
- 主题只依赖观察者接口,不依赖具体实现
✅ 符合开闭原则
- 新增观察者无需修改主题代码
✅ 支持广播通信
- 一个变化,多个对象响应
六、缺点
❌ 观察者过多时,通知可能影响性能
❌ 如果观察者之间有依赖,容易产生复杂关系
❌ 可能引起循环触发
七、适用场景
✅ 事件监听机制(GUI、按钮点击)
✅ 消息订阅、发布系统
✅ 数据变化需要同步更新多个模块
✅ MVC 架构(Model → View)
八、和“发布-订阅”模式的区别(常见误区)
| 观察者模式 | 发布-订阅模式 |
|---|---|
| 观察者直接依赖主题 | 通过中间“事件通道” |
| 通常同步 | 常异步 |
| 多用于面向对象 | 多用于消息系统 |
九、一句话总结
观察者模式就是:你关注我,我变了就自动告诉你。
如果你愿意,我也可以用 Spring 事件机制 / Vue 响应式 / 前端事件监听 的角度再给你讲一遍。