【前端设计模式】之观察者模式

观察者模式特性

观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其依赖者(观察者)会自动收到通知并更新。观察者模式的主要特性包括:

  1. 主题(Subject):也称为被观察者或发布者,负责维护一组观察者对象,并在状态变化时通知观察者。
  2. 观察者(Observer):也称为订阅者或监听器,负责接收主题的通知并进行相应的处理。
  3. 通知机制:主题在状态变化时会主动通知所有注册的观察者对象。 最佳实践及代码示例: 在前端开发中,观察者模式常用于以下场景:
  4. 事件处理:通过事件机制实现了观察者模式。DOM事件、自定义事件等都是基于观察者模式实现的。
  5. 数据绑定:当数据发生变化时,自动更新相关视图。

应用示例

// 定义主题对象
class Subject {constructor() {this.observers = [];}addObserver(observer) {this.observers.push(observer);}removeObserver(observer) {const index = this.observers.indexOf(observer);if (index !== -1) {this.observers.splice(index, 1);}}notify(data) {this.observers.forEach((observer) => {observer.update(data);});}
}
// 定义观察者对象
class Observer {update(data) {console.log(`Received data: ${data}`);// 处理接收到的数据}
}
// 使用示例
const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.notify("Hello World"); // 通知所有观察者,输出:Received data: Hello World

在上述示例中,我们定义了一个主题对象Subject和一个观察者对象Observer。主题对象负责维护一组观察者对象,并在状态变化时通知观察者。观察者对象通过注册到主题对象中,接收到主题的通知后进行相应的处理。

Vue双向绑定

Vue源码通过观察者模式实现了双向数据绑定。下面是Vue源码中实现双向绑定的大致代码实现:

  1. 首先,Vue通过Object.defineProperty方法对数据对象进行劫持,将其转化为响应式对象。在这个过程中,Vue会为每个属性创建一个Dep对象,用于收集依赖和通知更新。
  2. 在模板编译阶段,Vue会解析模板中的指令和表达式,并创建对应的指令对象。每个指令对象都会关联一个Watcher对象。
  3. Watcher对象负责订阅数据变化,并在数据变化时执行相应的回调函数。它会将自身添加到相关属性的依赖(Dep)中。
  4. 当数据发生变化时,被劫持的属性会触发相应的setter函数。在这个过程中,属性关联的依赖(Dep)会通知所有订阅者(即相关的Watcher)进行更新。
  5. 更新过程中,订阅者(即相关的Watcher)会执行回调函数,并更新视图。
 
// 定义观察者对象
class Watcher {constructor(vm, key, updateFn) {this.vm = vm;this.key = key;this.updateFn = updateFn;Dep.target = this;this.vm[this.key]; // 触发 getter,收集依赖Dep.target = null;}update() {this.updateFn.call(this.vm, this.vm[this.key]); // 更新视图}
}
// 定义依赖对象
class Dep {constructor() {this.subscribers = [];}depend() {if (Dep.target && !this.subscribers.includes(Dep.target)) {this.subscribers.push(Dep.target); // 收集依赖}}notify() {this.subscribers.forEach((subscriber) => subscriber.update()); // 通知更新}
}
// 定义响应式数据劫持函数
function defineReactive(obj, key, val) {const dep = new Dep();Object.defineProperty(obj, key, {get() {dep.depend(); // 收集依赖return val;},set(newVal) {if (newVal !== val) {val = newVal;dep.notify(); // 通知更新}},});
}
// 创建Vue实例
class Vue {constructor(options) {this.data = options.data;for (let key in this.data) {defineReactive(this.data, key, this.data[key]);}new Watcher(this, options.key, options.updateFn);}
}

以上是对Vue源码实现双向绑定的简要描述。定义了Watcher观察者对象和Dep依赖对象。在defineReactive函数中,我们使用Object.defineProperty对数据对象进行劫持,当数据发生变化时,会触发相应的gettersetter函数。在getter函数中,我们收集依赖;在setter函数中,我们通知依赖进行更新。通过创建Vue实例时创建的观察者对象,我们实现了数据和视图之间的双向绑定。

需要注意的是,以上示例是对Vue源码实现双向绑定的简化描述,并不包含Vue源码中的所有细节和优化,实际的实现细节更加复杂。Vue源码中还包含了更多的优化和处理逻辑,例如异步更新、依赖追踪、批量更新等。这些细节使得Vue的双向绑定更加高效和可靠。

Vue通过观察者模式实现了双向数据绑定。它通过劫持数据对象、创建依赖关系、订阅数据变化等步骤,实现了数据和视图之间的自动同步。这种机制使得开发者可以专注于业务逻辑而不必手动操作DOM元素。

优缺点

优点
  1. 解耦:主题和观察者之间解耦,使得它们可以独立变化。
  2. 可扩展性:可以方便地添加新的观察者或删除现有的观察者。
  3. 灵活性:可以动态地添加或删除观察者,根据需求选择订阅感兴趣的事件。
缺点
  1. 观察者过多时可能影响性能。
  2. 观察者和主题之间的关系可能变得复杂

总结

观察者模式是一种常用的设计模式,在前端开发中有广泛应用。它通过定义一种一对多的依赖关系,实现了对象之间的解耦和灵活性。通过使用观察者模式,可以实现事件处理、数据绑定、响应式系统等功能。然而,需要根据具体情况权衡使用观察者模式所带来的优缺点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/87136.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker 配置 gpu版pytorch环境--部署缺陷检测--Anomalib

目录 一、docker 配置 gpu版pyhorch环境1、显卡驱动、cuda版本、pytorch cuda版本三者对应2、拉取镜像 二、部署Anomalib1、下载Anomalib2、创建容器并且运行3、安装Anomalib进入项目路径安装依赖测试: 一、docker 配置 gpu版pyhorch环境 1、显卡驱动、cuda版本、p…

计算机视觉与深度学习-经典网络解析-GoogLeNet-[北邮鲁鹏]

这里写目录标题 GoogLeNet参考GoogLeNet模型结构创新点Inception结构,它能保留输入信号中的更多特征信息去掉了AlexNet的前两个全连接层,并采用了平均池化引入了辅助分类器 GoogLeNet GoogLeNet的设计主要特点是引入了Inception模块,这是一种…

ICA、TJA、ACC、ICC

原文链接1:https://www.dongchedi.com/article/7265878226768052772 原文链接2:https://www.toutiao.com/article/7144570305288356367/?wid1695348807250 ICA,Intergrated Cruise Assist,集成式巡航辅助系统 既能跟车又能保持车…

oracle客户端的安装(SQL Developer)

参考资料 软件首页:https://www.oracle.com/database/sqldeveloper/ 官方文档:https://docs.oracle.com/en/database/oracle/sql-developer/ 下载地址:https://www.oracle.com/database/sqldeveloper/technologies/download/ 安装指南&#…

GLTF编辑器 解析什么是模型粗糙度

1、什么是模型粗糙度 模型粗糙度(roughness)通常用于计算机图形学中的PBR(Physically Based Rendering,基于物理的渲染)模型中。 PBR模型是一种基于物理光学原理和材料属性的渲染方法,能够更加准确地还原物…

全国职业技能大赛云计算--高职组赛题卷④(容器云)

全国职业技能大赛云计算--高职组赛题卷④(容器云) 第二场次题目:容器云平台部署与运维任务1 Docker CE及私有仓库安装任务(5分)任务2 基于容器的web应用系统部署任务(15分)任务3 基于容器的持续…

使用 PyTorch 的计算机视觉简介 (2/6)

一、说明 在本单元中,我们从最简单的图像分类方法开始——一个全连接的神经网络,也称为感知器。我们将回顾一下 PyTorch 中定义神经网络的方式,以及训练算法的工作原理。 二、数据加载的实践 首先,我们使用 pytorchcv 助手来加载…

全球首发搭载“舱驾一体”的智能座舱,诺博汽车如何引领未来出行?

智能座舱升级战已经全面打响。 一方面,智能座舱已经进入了3.0时代,车企对于差异化要求越来越高,如何进一步提升单一功能体验并进行深度融合,已经成为了智能座舱市场比拼的重点。 另一方面,在5G、车联网、大数据、人工…

14.抽象工厂模式

UML 代码 #include <iostream> #include <list> using namespace std;class AbstractProductA { public:virtual void showa() 0; }; class ProductA1:public AbstractProductA { public:virtual void showa(){cout << "我是A1" << endl;}…

【线性回归、岭回归、Lasso回归分别预测患者糖尿病病情】数据挖掘实验一

Ⅰ、项目任务要求 任务描述&#xff1a;将“diabetes”糖尿病患者数据集划分为训练集和测试集&#xff0c;利用训练集分别结合线性回归、岭回归、Lasso回归建立预测模型&#xff0c;再利用测试集来预测糖尿病患者病情并验证预测模型的拟合能力。具体任务要求如下&#xff1a; …

[LLM+AIGC] 01.应用篇之中文ChatGPT初探及利用ChatGPT润色论文对比浅析(文心一言 | 讯飞星火)

近年来&#xff0c;人工智能技术火热发展&#xff0c;尤其是OpenAI在2022年11月30日发布ChatGPT聊天机器人程序&#xff0c;其使用了Transformer神经网络架构&#xff08;GPT-3.5&#xff09;&#xff0c;能够基于在预训练阶段所见的模式、统计规律和知识来生成回答&#xff0c…

电脑C盘爆红怎么办?(小白篇)

文章目录 前言&#xff1a;1、清理临时和系统文件2、更改电脑默认软件安装位置3、微信、QQ文件存储路径放在其它盘4、卸载一些不常用的软件彩蛋 前言&#xff1a; C盘作为电脑的系统盘&#xff0c;如果出现爆满或者剩余空间很小整个C盘变红&#xff0c;这样会导致电脑系统运行…

react获取Datepicker组件日期

当用户在输入字段中键入时&#xff0c;onChange事件将触发&#xff0c;并更新inputValue状态变量。这使得React重新渲染组件&#xff0c;并将输入字段的值更新为最新的inputValue。 import React from react; import DatePicker from material-ui/DatePicker;class MyComponen…

前端项目练习(练习-001-纯原生)

先创建一个空文件夹&#xff0c;名字为web-001,然后用idea开发工具打开&#xff0c;如图&#xff1a; 可以看到&#xff0c;这是个彻底的空项目&#xff0c;创建 index.html index.js index.css三个文件&#xff0c;如图&#xff1a; 其中&#xff0c;html文件内容如下&am…

华为OD机试 - 最小传输时延 - 深度优先搜索DFS(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明计算源节点1到目的节点5&#xff0c;符合要求的时延集合 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&…

时间复杂度、空间复杂度

一、时间复杂度 1、概念 时间复杂度&#xff1a;计算的是当一个问题量级增加的时间&#xff0c;时间增长的趋势&#xff1b; O&#xff08;大O表示法&#xff09;&#xff1a;渐进的时间复杂度 2、举例 ① 以下 for 循环的时间复杂度&#xff1a;O(1 3n) O(n) 去掉常数…

数据结构上机练习——单链表的基本操作、头文件、类定义、main函数、多种链表算法的实现,含注释

文章目录 单链表的基本操作实现1.头文件2.类定义和多种算法的实现2.1创建空表2.2头插法创建n个元素的线性链表2.3一个带头节点的链表存放一组整数&#xff0c;设计一个算法删除值等于x的所有节点。2.4计算线性表中值为偶数的节点个数2.5一个带头节点的单链表heada存放一组整数&…

nginx实现反向代理实例

1 前言 1.1 演示内容 在服务器上访问nginx端口然后跳转到tomcat服务器 1.2 前提条件 前提条件&#xff1a;利用docker安装好nginx、tomcat、jdk8&#xff08;tomcat运行需要jdk环境&#xff09; 只演示docker安装tomcat&#xff1a; 默认拉取最新版tomcat docker pull t…

Qt地铁智慧换乘系统浅学( 三 )最少路径和最少换乘实现

本算法全都基于广度优先 概念最短路径实现所用容器算法思路 最少换乘实现所需容器算法思路 成果展示代码实现判断是最短路径还是最少换乘最短路径代码实现最少换乘代码实现根据所得List画出线路 ui界面的维护&#xff08;前提条件&#xff09;界面初始化combox控件建立槽函数 概…

84、Redis客户端-->可视化图形界面工具(Another Redis Desktop Manager)的下载、安装及初步使用

Redis客户端–>可视化图形界面工具(Another Redis Desktop Manager)的下载、安装及初步使用 ★ Redis客户端&#xff1a; ▲ Redis自带的命令行工具&#xff08;简陋&#xff09;&#xff1a; CLI工具&#xff0c;重新打开一个命令行窗口&#xff0c;在其中输入如下命令&…