观察者模式
观察者模式(Observer Pattern)是一种行为型设计模式,实现了一种类似“订阅”的机制。它包含两个核心角色:观察者(订阅消息、接收通知并执行操作)和被观察者(维护观察者列表、在状态变化时通知所有观察者)。两者通过一对多关系实现解耦:被观察者只负责“通知”,观察者只负责“响应”。
在真实世界中可以类比为:商店老板(被观察者)记录客户(观察者)的需求,当商品到货(状态变化)后,老板通知所有登记过的客户。
在前端中,DOM 事件监听、MutationObserver 等机制也体现了观察者模式的思想。
基本流程(发生了什么)
- 客户端创建被观察者(Subject)实例
- 客户端创建多个观察者(Observer)实例
- 观察者向被观察者发起订阅(
subscribe/attach) - 被观察者在合适时机发布消息/状态变更(
notify) 所有观察者收到通知并执行各自的
update逻辑


4. TypeScript 示例(接口约束 + Store 维护观察者列表)

下面示例中:
IObserver<T>:观察者必须实现的约束(必须有update)Store<T>:被观察者,内部维护observers列表,支持subscribe/unsubscribe/notify
// 观察者接口:成为观察者必须实现 update
export interface IObserver<T> {
update(payload: T): void;
}
// 被观察者:维护观察者列表并负责通知
export class Store<T> {
private observers = new Set<IObserver<T>>();
subscribe(observer: IObserver<T>) {
this.observers.add(observer);
}
unsubscribe(observer: IObserver<T>) {
this.observers.delete(observer);
}
notify(payload: T) {
for (const observer of this.observers) {
observer.update(payload);
}
}
}客户端使用示例:
import { IObserver, Store } from "./store";
type GoodsArrived = { sku: string; name: string; count: number };
class CustomerA implements IObserver<GoodsArrived> {
update(payload: GoodsArrived) {
console.log("CustomerA 收到通知:", payload);
}
}
class CustomerB implements IObserver<GoodsArrived> {
update(payload: GoodsArrived) {
console.log("CustomerB 收到通知:", payload);
}
}
const boss = new Store<GoodsArrived>();
const a = new CustomerA();
const b = new CustomerB();
boss.subscribe(a);
boss.subscribe(b);
// 老板“到货”并通知所有登记客户
boss.notify({ sku: "10086", name: "Apple", count: 10 });要点:
- 被观察者负责:维护列表 + 通知
- 观察者负责:接收消息后的处理
5. 前端中的典型体现
5.1 DOM 事件监听
button.addEventListener("click", () => {
console.log("点击事件触发");
});这里按钮的点击事件发生时,会通知所有注册的监听器(观察者回调)。
5.2 MutationObserver
const observer = new MutationObserver((mutations) => {
console.log("DOM 发生变化:", mutations);
});
observer.observe(document.body, {
childList: true,
subtree: true,
});DOM 变化时,观察者回调会被触发。
6. 观察者模式 vs 发布订阅模式
二者常被混用,但并不相同:
- 观察者模式:观察者与被观察者之间通常存在直接依赖关系(Subject 直接持有 Observer 列表并逐个通知)
- 发布订阅模式(Pub/Sub):发布者与订阅者通常不直接相互引用,通过“事件总线/消息代理(Broker)”中转解耦(发布者只发布到 Broker,订阅者只从 Broker 订阅)
简单理解:观察者模式是“对象之间直接订阅与通知”,发布订阅模式是“通过中间件/消息中心解耦”。