前端开发设计模式——观察者模式

目录

一、定义和特点

1. 定义

2. 特点

二、实现方式

1. 使用 JavaScript 实现观察者模式的基本结构

2. 实际应用中的实现示例

三、使用场景

1. 事件处理

2. 数据绑定

3. 异步通信

4. 组件通信

四、优点

1. 解耦和灵活性

2. 实时响应和数据一致性

3. 提高代码的可复用性

五、缺点

1. 内存泄漏风险

2. 通知顺序和复杂性

3. 性能开销

六、注意事项

1. 正确管理观察者的生命周期

2. 注意通知的频率和时机

3. 处理好观察者之间的关系

4. 测试和调试


一、定义和特点

1. 定义

        观察者模式是一种软件设计模式,它定义了对象之间的一种一对多的依赖关系。当一个对象(被观察对象,也称为主题或可观察对象)的状态发生改变时,所有依赖于它的对象(观察者)都会得到通知并自动更新。

2. 特点

  • 一对多关系:一个主题可以有多个观察者与之关联。主题负责通知观察者,而观察者只需关注主题的状态变化并做出相应反应,它们之间的耦合度较低。
  • 自动更新:观察者无需主动查询主题的状态,而是在主题状态变化时自动接收通知并进行更新操作,保证了数据的一致性和及时性。
  • 解耦性强:主题和观察者相互独立,它们只通过定义好的接口进行交互。这使得系统的各个模块可以独立开发、修改和扩展,增强了系统的灵活性和可维护性。

二、实现方式

1. 使用 JavaScript 实现观察者模式的基本结构

// 定义主题(可观察对象)类
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);}}// 通知观察者状态更新notifyObservers() {this.observers.forEach(observer => {observer.update(this);});}
}// 定义观察者类
class Observer {update(subject) {// 在这里实现具体的更新逻辑,不同的观察者可以有不同的实现console.log('观察者收到主题状态更新通知');}
}

2. 实际应用中的实现示例

        假设我们正在开发一个简单的天气预报应用,其中天气数据是主题,而在页面上显示天气信息的组件以及根据天气情况进行提醒的功能模块等都是观察者。

// 天气数据主题类
class WeatherData extends Subject {constructor() {super();this.temperature = 0;this.humidity = 0;}// 更新天气数据并通知观察者setWeatherData(newTemperature, newHumidity) {this.temperature = newTemperature;this.humidity = newHumidity;this.notifyObservers();}
}// 显示天气信息的观察者类
class DisplayWeatherObserver extends Observer {update(weatherData) {const temperature = weatherData.temperature;const humidity = weatherData.humidity;// 在这里更新页面上显示天气信息的元素document.getElementById('temperature').textContent = `温度: ${temperature}°C`;document.getElementById('humidity').textContent = `湿度: ${humidity}%`;}
}// 天气提醒观察者类
class WeatherAlertObserver extends Observer {update(weatherData) {const temperature = weatherData.temperature;const humidity = weatherData.humidity;// 根据天气情况进行提醒if (temperature > 30 && humidity > 70) {alert('天气炎热潮湿,注意防暑防潮!');}}
}// 使用示例
const weatherData = new WeatherData();
const displayObserver = new DisplayWeatherObserver();
const alertObserver = new WeatherAlertObserver();weatherData.addObserver(displayObserver);
weatherData.addObserver(alertObserver);// 模拟天气数据更新
weatherData.setWeatherData(28, 60);
weatherData.setWeatherData(32, 75);

        在上述示例中,WeatherData类作为主题,负责维护天气数据和观察者列表,并在数据更新时通知观察者。DisplayWeatherObserverWeatherAlertObserver类分别是不同的观察者,它们根据主题的通知进行相应的操作,一个更新页面显示,一个进行天气提醒

三、使用场景

1. 事件处理

        在前端页面中,用户的交互操作会触发各种事件,如按钮点击、表单提交等。可以将触发事件的元素看作主题,而处理这些事件的函数或模块看作观察者。例如,当用户点击一个登录按钮时,按钮是主题,登录验证逻辑、页面跳转逻辑等都是观察者,按钮点击后(主题状态改变),相应的观察者会执行各自的任务。

2. 数据绑定

        在现代前端框架中广泛应用的数据双向绑定机制通常基于观察者模式实现。当数据模型(主题)发生变化时,与之绑定的视图(观察者)会自动更新显示;反之,当用户在视图中进行操作修改数据时,数据模型也会相应更新,同时通知其他相关的视图进行更新。例如,在 Vue.js 中,当一个数据属性发生变化时,所有依赖该属性的模板部分都会自动重新渲染。

3. 异步通信

        当进行异步数据请求(如 AJAX 请求获取数据)时,请求对象可以看作主题,而请求成功后的后续处理逻辑(如更新页面数据、显示提示信息等)可以看作观察者。一旦数据请求完成(主题状态改变为获取到数据),观察者就会收到通知并进行相应的处理。

4. 组件通信

        在大型前端应用中,不同组件之间可能需要进行通信。例如,一个父组件可以作为主题,子组件作为观察者。当父组件的某些数据或状态发生变化时,它可以通知子组件进行相应的更新或操作,而子组件无需直接访问父组件的内部状态,保持了组件之间的独立性和解耦性。

四、优点

1. 解耦和灵活性

        主题和观察者之间的松散耦合使得它们可以独立变化和扩展。可以方便地添加新的观察者或修改现有观察者的行为,而不需要对主题的代码进行大量修改。同样,主题的内部实现可以改变,只要它仍然能够正确地通知观察者状态变化,观察者的代码也无需做太大调整。这使得系统更容易维护和扩展,适应不断变化的需求。

2. 实时响应和数据一致性

        观察者能够实时接收到主题状态变化的通知,并立即进行相应的更新操作,保证了系统中数据的一致性。用户在前端界面上看到的信息始终是最新的,提升了用户体验。例如,在数据绑定的场景中,用户对数据的修改可以立即反映在界面上,反之亦然。

3. 提高代码的可复用性

        观察者模式将不同的功能模块(观察者)分离出来,每个观察者只关注自己的特定任务和对主题状态变化的响应。这些观察者可以在不同的项目或场景中复用,只需要将它们与适当的主题进行关联即可。例如,一个用于显示数据变化的观察者组件可以在多个不同的数据展示页面中使用。

五、缺点

1. 内存泄漏风险

        如果在观察者不再需要关注主题状态变化时,没有正确地从主题的观察者列表中删除,那么即使观察者所关联的对象已经不再使用,它仍然会占用内存。这可能导致内存泄漏问题,尤其是在长时间运行的前端应用中。例如,当一个页面组件被销毁,但与之绑定的观察者没有被解除绑定,就会出现这种情况。

2. 通知顺序和复杂性

        当有多个观察者时,通知的顺序可能会影响系统的行为和结果。如果观察者之间存在依赖关系或者对通知顺序有要求,需要额外的机制来保证通知的正确顺序,这会增加系统的复杂性。而且,在复杂的系统中,可能难以追踪和理解所有观察者之间的交互关系以及它们对主题状态变化的响应逻辑。

3. 性能开销

        当主题频繁地发生状态变化并且有大量观察者时,通知所有观察者并执行它们的更新方法可能会带来一定的性能开销。特别是当观察者的更新操作比较复杂或者耗时较长时,可能会影响系统的整体性能和响应速度。例如,在一个实时数据更新的场景中,如果每秒都有大量数据更新并且有多个观察者进行复杂的计算和渲染操作,可能会导致页面卡顿。

六、注意事项

1. 正确管理观察者的生命周期

        在添加观察者时,要确保在合适的时机(通常是在观察者对象创建并准备好接收通知时)进行添加操作。同时,当观察者不再需要关注主题状态时,一定要及时从主题的观察者列表中删除,以避免内存泄漏。可以在观察者对象的销毁方法或者相关的生命周期钩子函数中执行删除操作。

2. 注意通知的频率和时机

        要合理控制主题状态变化的通知频率,避免过于频繁的通知导致性能问题。可以考虑对主题的状态变化进行适当的缓存或合并处理,在一定条件下再进行通知。同时,要确保通知的时机是合适的,即在主题的状态确实发生了有意义的变化并且观察者需要进行相应处理时才发送通知。

3. 处理好观察者之间的关系

        如果多个观察者之间存在依赖关系或者需要协同工作,要设计好它们之间的交互方式和顺序。可以通过引入中间协调者或者规定明确的通知顺序规则来解决。同时,要注意避免观察者之间的循环依赖等问题,以免导致系统出现异常行为或死锁。

4. 测试和调试

        由于观察者模式涉及多个对象之间的交互,在开发过程中要进行充分的测试和调试。可以编写单元测试来验证主题和观察者的功能是否正确,以及它们之间的交互是否符合预期。在调试时,可以利用浏览器的开发者工具等手段来跟踪观察对象的状态变化和通知过程,以便及时发现和解决问题。

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

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

相关文章

少儿编程学习中的家庭支持:家长角色如何从监督到参与?

随着少儿编程教育的普及,越来越多的家庭开始意识到编程对孩子未来发展的重要性。编程不仅仅是一项技术技能,更是培养逻辑思维、解决问题能力和创新意识的有效途径。然而,如何在家庭中正确支持孩子的编程学习,对家长而言是一个新的…

EJB项目如何升级SpringCloud

记录某金融机构老项目重构升级为微服务过程1 如何从EJB架构拆分微服务 这个非常有趣的过程,整个过程耗时大致接近半年时光,需要考虑到重构升级保留原来的业务线,而且还要考虑后续的维护成本,保留现有的数据库表结构,…

基于SpringBoot的在线医疗问答平台

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…

如何使用 Python 操作数据库

😀前言 在现代编程中,Python 的数据库操作已广泛应用于各类项目中,例如数据分析、Web 开发和数据持久化存储等。本文将介绍 Python 操作数据库的核心步骤,涉及数据库连接对象、游标对象的使用,以及常见的 SQL 数据操作…

夸克浏览器的用户反馈如何提交

夸克浏览器凭借其简洁的界面、强大的功能以及不断优化的用户体验,赢得了众多用户的青睐。然而,任何产品都不可能完美无缺,用户的反馈对于产品的持续改进至关重要。本文将详细介绍如何在夸克浏览器中高效提交用户反馈,帮助开发者更…

【移动应用开发】使用多媒体--通知/播放音频/视频

目录 一、具体步骤 二、运行截图 1. 开启通知权限 2. 播放音乐 3. 播放视频 三、源代码 1. activity_main.xml 2. activity_video_player.xml 3. activity_notification.xml 4. 一些配置 5. MainActivity 6. VideoPlayerActivity 7. NotificationActivity 8. And…

VulnHub-Brainpan1 靶机笔记

Brainpan1 靶机笔记 概述 靶机地址:https://vulnhub.com/entry/brainpan-1,51/#download 这台靶机是很好的缓冲区溢出漏洞利用的练习靶机,涉及到逆向和缓冲区溢出漏洞挖掘的一些知识。 一、nmap 扫描 1)端口扫描 nmap -sT --min-rate 1…

echarts实现 水库高程模拟图表

需求背景解决思路解决效果index.vue 需求背景 需要做一个水库高程模拟的图表&#xff0c;x轴是水平距离&#xff0c;y轴是高程&#xff0c;需要模拟改水库的形状 echarts 图表集链接 解决思路 配合ui切图&#xff0c;模拟水库形状 解决效果 index.vue <!--/*** author:…

【Linux探索学习】第九弹——Linux工具篇(四):项目自动化构建工具—make/Makefile

Linux笔记&#xff1a;https://blog.csdn.net/2301_80220607/category_12805278.html?spm1001.2014.3001.5482 前言&#xff1a; 在前面我们学习了如何用编译并执行&#xff0c;在现代软件开发中&#xff0c;构建一个项目涉及多个步骤&#xff0c;从编译源代码到链接库文件&a…

基于SpringBoot+Vue+MySQL的房屋租赁系统

系统展示 系统背景 随着城市化进程的加速和人口流动性的增加&#xff0c;房屋租赁市场逐渐成为城市生活的重要组成部分。然而&#xff0c;传统的房屋租赁方式存在诸多问题&#xff0c;如信息不对称、交易成本高、租赁关系不稳定等&#xff0c;这些问题严重影响了租赁市场的健康…

View三大机制(一):触摸机制(事件分发)

传递过程遵循如下顺序&#xff1a;Activity->Window->PhoneWindow->DecorView->RootView->ViewGroup->View View事件方法执行顺序:onTouchListener > onTouchEvent > onLongClickListener > onClickListener 主要由三个重要的方法共同完成的,只有Vi…

namespace 隔离实战

Docker简介 什么是虚拟化、容器化为什么要虚拟化、容器化?虚拟化实现 什么是虚拟化、容器化 物理机: 实际的服务器或者计算机。相对于虚拟机而言的对实体计算机的称呼。物理机提供给虚拟机以硬件环境&#xff0c;有时也称为“寄主”或“宿主”。 虚拟化: 是指通过虚拟化技术将…

Canvas 画布

文章目录 1. 初识1.1 认识画布1.2 兼容性1.3 上下文属性 2. 绘制2.1 绘制基本图形2.1.1 绘制矩形2.1.2 绘制圆形2.1.3 绘制直线2.1.4 绘制圆弧2.1.5 绘制贝塞尔二次曲线2.1.6 绘制贝塞尔三次曲线2.1.7 封装路径 2.2 颜色控制2.2.1 颜色设置2.2.2 线性渐变2.2.3 径向渐变2.2.4 圆…

XML解析小坑记录[正则表达式解析]

一、问题描述 在做 SSO 单点登录时( 认证中为CAS服务对接 )。在完成对用户ticket票根校验后&#xff0c;返回了用户信息有关 XML 数据片段&#xff0c;例如下&#xff1a; <cas:serviceResponse xmlns:cas"http://www.xxx.xx/xx/cas"><cas:authentication…

ffmpeg视频滤镜:网格-drawgrid

滤镜介绍 drawgrid 官网链接 》 FFmpeg Filters Documentation drawgrid会在视频上画一个网格。 滤镜使用 参数 x <string> ..FV.....T. set horizontal offset (default "0")y <string> ..FV.....T. set…

(50)MATLAB最优延迟迫零均衡器仿真测试与评估

文章目录 前言一、最优延迟迫零均衡器评估模型二、最优延迟迫零均衡器仿真代码1.代码如下&#xff1a;2.迫零均衡器函数zf_equalizer()的MATLAB源码 三、仿真结果画图1.不同权系数长度和延迟的迫零均衡器性能2. 不同权系数长度的迫零均衡器的最佳延迟 前言 对于预设均衡器延时…

用AI绘画工具提升创作效率,这款神器你一定不能错过!

在如今的创作领域&#xff0c;无论是插画师、设计师&#xff0c;还是内容创作者&#xff0c;都在寻找能够提升效率的工具&#xff0c;而AI绘画工具的诞生无疑是一场创意革命。通过AI技术的支持&#xff0c;我们不再需要耗费大量时间在绘制基础草图或反复调整细节上&#xff0c;…

为什么要使用Golang以及如何入门

什么是golang&#xff1f; Go是一种开放源代码的编程语言&#xff0c;于2009年首次发布&#xff0c;由Google的Rob Pike&#xff0c;Robert Griesemer和Ken Thompson开发。基于C的语法&#xff0c;它进行了一些更改和改进&#xff0c;以安全地管理内存使用&#xff0c;管理对象…

Oracle故障诊断(一线DBA必备技能)之ADRCI(四)

1. 题记&#xff1a; 本篇博文继续详细介绍一线DBA必备技能—Oracle DB故障诊断工具ADRCI。 2. 使用 ADRCI 进行故障诊断的步骤 1. 查看警报日志 警报日志是故障诊断的重要信息源&#xff0c;它记录了数据库启动、关闭、错误消息等关键事件。 首先启动 ADRCI。在操作系统命…

基于SpringBoot的项目工时统计成本核算管理源码带教程

该系统是基于若依前后端分离的架构&#xff0c;前端使用vue2&#xff0c;后端使用SpringBoot2。 技术框架&#xff1a;SpringBoot2.0.0 Mybatis1.3.2 Shiro swagger-ui jpa lombok Vue2 Mysql5.7 运行环境&#xff1a;jdk8 IntelliJ IDEA maven 宝塔面板 系统与功…