什么是观察者模式?JavaScript 实现一个观察者模式的示例
·
什么是观察者模式?
观察者模式(Observer Pattern)是一种行为型设计模式,它定义了对象之间的一对多依赖关系:当一个对象(被观察者)的状态发生变化时,所有依赖它的对象(观察者)会自动收到通知并更新。
这种模式的核心是解耦被观察者和观察者,让它们可以独立变化。被观察者只需维护一个观察者列表,无需知道具体观察者的细节;观察者只需等待通知,无需主动查询被观察者的状态。
观察者模式的核心角色
- 被观察者(Subject):也称为 “主题”,维护一个观察者列表,提供添加、移除观察者的方法,以及在状态变化时通知所有观察者的方法。
- 观察者(Observer):定义一个更新接口,当收到被观察者的通知时,执行相应的更新操作。
- 具体被观察者(ConcreteSubject):被观察者的具体实现,当自身状态变化时,触发通知方法。
- 具体观察者(ConcreteObserver):观察者的具体实现,实现更新接口,根据被观察者的通知执行具体逻辑。
JavaScript 实现观察者模式示例:新闻订阅系统
以下以 “新闻订阅” 为例,实现观察者模式。场景是:一个新闻发布平台(被观察者)有多个用户(观察者)订阅,当平台发布新新闻时,所有订阅用户会收到推送并查看新闻。
代码实现 - javascript
// -------------- 1. 被观察者(新闻发布平台)--------------
class NewsSubject {
constructor() {
this.observers = []; // 存储观察者列表
this.latestNews = null; // 最新新闻
}
// 添加观察者(订阅)
addObserver(observer) {
this.observers.push(observer);
}
// 移除观察者(取消订阅)
removeObserver(observer) {
this.observers = this.observers.filter(obs => obs !== observer);
}
// 通知所有观察者(发布新闻时触发)
notifyObservers() {
this.observers.forEach(observer => {
observer.update(this.latestNews); // 向观察者传递最新新闻
});
}
// 发布新闻(更新被观察者状态)
publishNews(news) {
this.latestNews = news;
console.log(`平台发布新闻:${news}`);
this.notifyObservers(); // 状态变化后通知观察者
}
}
// -------------- 2. 观察者接口(用户订阅者)--------------
class Observer {
// 抽象更新方法(由具体观察者实现)
update(news) {
throw new Error("子类必须实现 update 方法");
}
}
// -------------- 3. 具体观察者(不同用户)--------------
// 用户A:收到新闻后打印详情
class UserA extends Observer {
update(news) {
console.log(`用户A收到新闻:${news},正在阅读...`);
}
}
// 用户B:收到新闻后转发
class UserB extends Observer {
update(news) {
console.log(`用户B收到新闻:${news},已转发到朋友圈!`);
}
}
// 用户C:收到新闻后收藏
class UserC extends Observer {
update(news) {
console.log(`用户C收到新闻:${news},已收藏!`);
}
}
// -------------- 4. 客户端使用 --------------
// 创建被观察者(新闻平台)
const newsPlatform = new NewsSubject();
// 创建观察者(用户)
const userA = new UserA();
const userB = new UserB();
const userC = new UserC();
// 用户订阅新闻
newsPlatform.addObserver(userA);
newsPlatform.addObserver(userB);
newsPlatform.addObserver(userC);
// 平台发布第一条新闻
newsPlatform.publishNews("JavaScript 设计模式详解");
// 输出:
// 平台发布新闻:JavaScript 设计模式详解
// 用户A收到新闻:JavaScript 设计模式详解,正在阅读...
// 用户B收到新闻:JavaScript 设计模式详解,已转发到朋友圈!
// 用户C收到新闻:JavaScript 设计模式详解,已收藏!
// 用户B取消订阅
newsPlatform.removeObserver(userB);
console.log("\n用户B已取消订阅\n");
// 平台发布第二条新闻
newsPlatform.publishNews("前端性能优化实战");
// 输出:
// 平台发布新闻:前端性能优化实战
// 用户A收到新闻:前端性能优化实战,正在阅读...
// 用户C收到新闻:前端性能优化实战,已收藏!
代码说明
-
被观察者(NewsSubject):
- 维护
observers列表存储所有订阅的观察者,提供addObserver(订阅)、removeObserver(取消订阅)方法。 - 当调用
publishNews发布新闻时,更新自身状态(latestNews),并通过notifyObservers通知所有观察者。
- 维护
-
观察者(Observer):定义抽象方法
update,规定所有具体观察者必须实现该方法以接收通知。 -
具体观察者(UserA、UserB 等):实现
update方法,根据自身需求处理新闻(阅读、转发、收藏),无需关心新闻的发布逻辑。 -
核心优势:
- 解耦:新闻平台(被观察者)无需知道用户(观察者)的具体操作,用户也无需主动查询新闻,只需等待通知。
- 可扩展性:新增用户(如 UserD)只需实现
Observer接口并订阅,无需修改平台代码;移除用户也不影响其他观察者。
观察者模式的常见应用场景
- 事件监听:浏览器的 DOM 事件(如
click、resize)本质是观察者模式,元素是被观察者,事件处理函数是观察者。 - 状态管理:React 的
useState、Vue 的响应式系统,当状态变化时,依赖该状态的组件(观察者)自动重新渲染。 - 消息通知:如公众号订阅、邮件推送,发布者(被观察者)更新内容后,所有订阅者(观察者)收到通知。
JavaScript 中的简化实现
由于 JavaScript 支持函数作为一等公民,可简化观察者模式(无需严格定义类,直接用函数作为观察者):
javascript
运行
class EventEmitter {
constructor() {
this.events = {}; // 存储事件与观察者的映射(键:事件名,值:回调数组)
}
// 订阅事件
on(event, callback) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(callback);
}
// 取消订阅
off(event, callback) {
if (this.events[event]) {
this.events[event] = this.events[event].filter(cb => cb !== callback);
}
}
// 触发事件(通知观察者)
emit(event, ...args) {
if (this.events[event]) {
this.events[event].forEach(callback => callback(...args));
}
}
}
// 使用示例
const emitter = new EventEmitter();
// 订阅 "news" 事件
const callback1 = (news) => console.log(`用户1收到:${news}`);
const callback2 = (news) => console.log(`用户2收到:${news}`);
emitter.on("news", callback1);
emitter.on("news", callback2);
// 触发事件
emitter.emit("news", "简化版观察者模式示例");
// 输出:
// 用户1收到:简化版观察者模式示例
// 用户2收到:简化版观察者模式示例
// 取消订阅
emitter.off("news", callback1);
emitter.emit("news", "取消订阅后测试");
// 输出:
// 用户2收到:取消订阅后测试
这种简化版类似 Node.js 的 EventEmitter,是 JavaScript 中最常用的观察者模式实现,广泛用于事件处理和状态管理。
观察者模式的核心是 “状态变化自动通知”,通过解耦实现了灵活的交互逻辑,是构建响应式系统的重要模式。
更多推荐


所有评论(0)