当前位置: 首页 > news >正文

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式

一、引入

在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如:

  • 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;
  • 新闻网站中,发布新新闻时需要推送给所有订阅该频道的读者;
  • 股票行情系统中,股票价格变动时需要实时通知所有关注该股票的投资者。

这些场景的共同特点是:多个对象之间存在依赖关系,一个对象的状态改变会影响到其他对象。如果直接在代码中硬编码这些依赖关系,会导致代码耦合度高、难以维护和扩展。此时,观察者模式(Observer Pattern)就能很好地解决这类问题。

读完本文,你将学会如何利用观察者模式实现对象间的消息通信,让代码在保持低耦合的同时,具备更强的可维护性和扩展性。

二、何为观察者模式

观察者模式是一种行为型设计模式,其核心思想是:定义对象间的一种一对多依赖关系,使得当一个对象(被观察者)的状态发生改变时,所有依赖于它的对象(观察者)都能自动收到通知并执行相应的操作。

核心角色

  • 被观察者(Subject):维护观察者列表,提供添加、删除观察者的方法,当状态变化时通知所有观察者。
  • 观察者(Observer):定义接收通知的接口,通常包含一个更新方法,用于在收到通知时执行具体操作。

实现思路
通过Proxy代理对象实现数据劫持,当被观察对象的属性发生变化时,自动触发通知逻辑,通知所有注册的观察者。

三、代码实现

我们以一个简单的人物信息对象为例,演示观察者模式的具体实现:

// 原始数据对象
const person = {name: 'ts',age: 21
}// 被观察者类
class Subject {constructor(value) {this.observers = []; // 存储观察者列表// 使用Proxy实现数据代理,监听属性变化const handler = {get: (self, key) => {return self[key];},set: (self, key, newVal) => {// 打印属性变化信息console.log(`${key}${self[key]}修改为${newVal}`);// 触发通知this.notify(key, newVal);self[key] = newVal; // 更新属性值return true;}};this.value = new Proxy(value, handler); // 生成代理对象}// 添加观察者add(observer) {this.observers.push(observer);}// 通知所有观察者notify(key, newVal) {this.observers.forEach(observer => observer.update(key, newVal));}
}// 观察者类
class Observer {constructor(value) {this.value = value; // 观察者自身的数据}// 更新方法,收到通知时执行update(key, value) {console.log(`${this.value.name}观察到${key}变化了,新的值是${value}`);this.value[key] = value; // 更新观察者自身的数据}
}// 创建被观察者实例,传入原始数据
const proxyPerson = new Subject(person);// 创建观察者实例
const obs1 = new Observer({ name: 'xll', age: 100 });
const obs2 = new Observer({ name: 'xhh', age: 3 });// 注册观察者
proxyPerson.add(obs1);
proxyPerson.add(obs2);// 修改被观察对象的属性,触发通知
proxyPerson.value.age = 10;
proxyPerson.value.name = 'js';

执行结果

age从21修改为10
xll观察到age变化了,新的值是10
xhh观察到age变化了,新的值是10
name从ts修改为js
xll观察到name变化了,新的值是js
xhh观察到name变化了,新的值是js

四、代码解析

  1. 被观察者(Subject)

    • 通过Proxy对原始数据对象进行代理,重写getset方法,实现对属性访问和修改的拦截。
    • 当属性被修改时,调用notify方法通知所有观察者。
    • add方法用于注册观察者,将观察者添加到观察者列表中。
  2. 观察者(Observer)

    • 每个观察者都有自己的状态数据(如obs1obs2nameage)。
    • update方法是观察者的核心逻辑,用于在收到通知时更新自身状态,并执行相应的业务操作(如打印日志)。
  3. 解耦与通知流程

    • 被观察者和观察者之间通过接口进行通信,彼此无需知道对方的具体实现,实现了低耦合。
    • 当被观察对象的属性发生变化时,通过Proxy自动触发通知,观察者被动接收通知并更新状态,形成了“数据变化→通知→更新”的完整流程。

五、观察者模式的优点

维度观察者模式直接调用方式
耦合性低耦合,对象间无需直接依赖高耦合,对象间直接调用
扩展性新增观察者无需修改被观察者新增功能需修改原始代码
复用性观察者可复用于多个被观察者功能复用性差
灵活性可动态添加/删除观察者功能绑定固定,难以调整

六、应用场景

  • 状态监控:监控服务器状态、设备状态等,当状态变化时通知相关系统或人员。
  • 消息订阅:实现消息发布-订阅系统,如邮件订阅、短信通知等。
  • 数据绑定:前端框架中的数据双向绑定(如Vue的响应式原理),本质上就是观察者模式的应用。
  • 事件驱动:浏览器中的事件监听(如点击事件、键盘事件等),也是观察者模式的典型场景。

通过观察者模式,我们可以将对象间的依赖关系从紧耦合变为松耦合,使系统更具灵活性和可扩展性。在后续的文章中,我们将继续探讨其他设计模式,帮助你写出更优雅、更易维护的代码。如果你有任何问题或建议,欢迎在评论区留言!

http://www.dtcms.com/a/234703.html

相关文章:

  • LabVIEW工业级多任务实时测控系统
  • ruoyi-plus-could 负载均衡 通过 Gateway模块配置负载均衡
  • UniApp系列
  • 华为OD最新机试真题-食堂供餐-OD统一考试(B卷)
  • Bootstrap 4 文件结构与 API 使用指南
  • 如何使用索引和条件批量更改Series数据
  • 交易系统开发:跨境资本的高速通道架构解密
  • HarmonyOS运动开发:如何用mpchart绘制运动配速图表
  • 父组件prop传向子组件的值,被子组件直接v-model绑定 功能不生效
  • 前端实现视频/直播预览
  • 深入理解 Python `asyncio` 的子进程协议(Subprocess Protocol)
  • Java-IO流之压缩与解压缩流详解
  • 阿里联合上海AI Lab提出DMM!多个模型压缩成一个通用T2I模型!可控任意风格生成!
  • Tomcat全方位监控实施方案指南
  • Python内置函数ord()详解
  • 数据库系统学习
  • M3T联邦基础模型用于具身智能:边缘集成的潜力与挑战
  • 8. 线性表的类型定义
  • 面向开发者的提示词工程④——文本推断(Inferring)
  • Qt(part1)Qpushbutton,信号与槽,对象树,自定义信号与槽,lamda表达式。
  • 人员定位系统解决方案
  • 记录一个用了很久的git提交到github和gitee比较方便的方法
  • 基于Javamail的邮件收发系统设计与实现【源码+文档】
  • NLP学习路线图(二十九):BERT及其变体
  • 三种读写传统xls格式文件开源库libxls、xlslib、BasicExcel的比较
  • 20250606-C#知识:List排序
  • 使用 Ansible 在 Windows 服务器上安装 SSL 证书
  • Opencv中的addweighted函数
  • [论文阅读] 人工智能 | 大语言模型计划生成的新范式:基于过程挖掘的技能学习
  • Linux-http协议