前端开发设计模式——观察者模式
目录
一、定义和特点
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
类作为主题,负责维护天气数据和观察者列表,并在数据更新时通知观察者。DisplayWeatherObserver
和WeatherAlertObserver
类分别是不同的观察者,它们根据主题的通知进行相应的操作,一个更新页面显示,一个进行天气提醒
三、使用场景
1. 事件处理
在前端页面中,用户的交互操作会触发各种事件,如按钮点击、表单提交等。可以将触发事件的元素看作主题,而处理这些事件的函数或模块看作观察者。例如,当用户点击一个登录按钮时,按钮是主题,登录验证逻辑、页面跳转逻辑等都是观察者,按钮点击后(主题状态改变),相应的观察者会执行各自的任务。
2. 数据绑定
在现代前端框架中广泛应用的数据双向绑定机制通常基于观察者模式实现。当数据模型(主题)发生变化时,与之绑定的视图(观察者)会自动更新显示;反之,当用户在视图中进行操作修改数据时,数据模型也会相应更新,同时通知其他相关的视图进行更新。例如,在 Vue.js 中,当一个数据属性发生变化时,所有依赖该属性的模板部分都会自动重新渲染。
3. 异步通信
当进行异步数据请求(如 AJAX 请求获取数据)时,请求对象可以看作主题,而请求成功后的后续处理逻辑(如更新页面数据、显示提示信息等)可以看作观察者。一旦数据请求完成(主题状态改变为获取到数据),观察者就会收到通知并进行相应的处理。
4. 组件通信
在大型前端应用中,不同组件之间可能需要进行通信。例如,一个父组件可以作为主题,子组件作为观察者。当父组件的某些数据或状态发生变化时,它可以通知子组件进行相应的更新或操作,而子组件无需直接访问父组件的内部状态,保持了组件之间的独立性和解耦性。
四、优点
1. 解耦和灵活性
主题和观察者之间的松散耦合使得它们可以独立变化和扩展。可以方便地添加新的观察者或修改现有观察者的行为,而不需要对主题的代码进行大量修改。同样,主题的内部实现可以改变,只要它仍然能够正确地通知观察者状态变化,观察者的代码也无需做太大调整。这使得系统更容易维护和扩展,适应不断变化的需求。
2. 实时响应和数据一致性
观察者能够实时接收到主题状态变化的通知,并立即进行相应的更新操作,保证了系统中数据的一致性。用户在前端界面上看到的信息始终是最新的,提升了用户体验。例如,在数据绑定的场景中,用户对数据的修改可以立即反映在界面上,反之亦然。
3. 提高代码的可复用性
观察者模式将不同的功能模块(观察者)分离出来,每个观察者只关注自己的特定任务和对主题状态变化的响应。这些观察者可以在不同的项目或场景中复用,只需要将它们与适当的主题进行关联即可。例如,一个用于显示数据变化的观察者组件可以在多个不同的数据展示页面中使用。
五、缺点
1. 内存泄漏风险
如果在观察者不再需要关注主题状态变化时,没有正确地从主题的观察者列表中删除,那么即使观察者所关联的对象已经不再使用,它仍然会占用内存。这可能导致内存泄漏问题,尤其是在长时间运行的前端应用中。例如,当一个页面组件被销毁,但与之绑定的观察者没有被解除绑定,就会出现这种情况。
2. 通知顺序和复杂性
当有多个观察者时,通知的顺序可能会影响系统的行为和结果。如果观察者之间存在依赖关系或者对通知顺序有要求,需要额外的机制来保证通知的正确顺序,这会增加系统的复杂性。而且,在复杂的系统中,可能难以追踪和理解所有观察者之间的交互关系以及它们对主题状态变化的响应逻辑。
3. 性能开销
当主题频繁地发生状态变化并且有大量观察者时,通知所有观察者并执行它们的更新方法可能会带来一定的性能开销。特别是当观察者的更新操作比较复杂或者耗时较长时,可能会影响系统的整体性能和响应速度。例如,在一个实时数据更新的场景中,如果每秒都有大量数据更新并且有多个观察者进行复杂的计算和渲染操作,可能会导致页面卡顿。
六、注意事项
1. 正确管理观察者的生命周期
在添加观察者时,要确保在合适的时机(通常是在观察者对象创建并准备好接收通知时)进行添加操作。同时,当观察者不再需要关注主题状态时,一定要及时从主题的观察者列表中删除,以避免内存泄漏。可以在观察者对象的销毁方法或者相关的生命周期钩子函数中执行删除操作。
2. 注意通知的频率和时机
要合理控制主题状态变化的通知频率,避免过于频繁的通知导致性能问题。可以考虑对主题的状态变化进行适当的缓存或合并处理,在一定条件下再进行通知。同时,要确保通知的时机是合适的,即在主题的状态确实发生了有意义的变化并且观察者需要进行相应处理时才发送通知。
3. 处理好观察者之间的关系
如果多个观察者之间存在依赖关系或者需要协同工作,要设计好它们之间的交互方式和顺序。可以通过引入中间协调者或者规定明确的通知顺序规则来解决。同时,要注意避免观察者之间的循环依赖等问题,以免导致系统出现异常行为或死锁。
4. 测试和调试
由于观察者模式涉及多个对象之间的交互,在开发过程中要进行充分的测试和调试。可以编写单元测试来验证主题和观察者的功能是否正确,以及它们之间的交互是否符合预期。在调试时,可以利用浏览器的开发者工具等手段来跟踪观察对象的状态变化和通知过程,以便及时发现和解决问题。
相关文章:
前端开发设计模式——观察者模式
目录 一、定义和特点 1. 定义 2. 特点 二、实现方式 1. 使用 JavaScript 实现观察者模式的基本结构 2. 实际应用中的实现示例 三、使用场景 1. 事件处理 2. 数据绑定 3. 异步通信 4. 组件通信 四、优点 1. 解耦和灵活性 2. 实时响应和数据一致性 3. 提高代码的可…...
永磁同步电机高性能控制算法(17)——无差拍预测转速控制
1.前言 前期写了比较多的关于无差拍预测电流控制的东西。 https://zhuanlan.zhihu.com/p/659205719https://zhuanlan.zhihu.com/p/659205719 https://zhuanlan.zhihu.com/p/660266190https://zhuanlan.zhihu.com/p/660266190 https://zhuanlan.zhihu.com/p/719591343https://z…...
【GIT】Visual Studio 中 Git 界面中, 重置 和 还原
在 Visual Studio 的 Git 界面中,“重置” 和 “还原” 是两个常用的 Git 操作。它们的主要区别在于应用场景和影响范围。 1. 重置(Reset) 重置用于更改当前分支的提交历史,通常用于撤销或删除某些提交。重置操作可能会更改 Git…...
开源一款前后端分离的企业级网站内容管理系统,支持站群管理、多平台静态化,多语言、全文检索的源码
大家好,我是一颗甜苞谷,今天分享一款前后端分离的企业级网站内容管理系统,支持站群管理、多平台静态化,多语言、全文检索的源码。 前言 在当今的数字化时代,企业网站和个人博客已成为信息传播和品牌建设的重要渠道。…...
【electron+vue3】使用JustAuth实现第三方登录(前后端完整版)
实现过程 去第三方平台拿到client-id和client-secret,并配置一个能够外网访问回调地址redirect-uri供第三方服务回调搭建后端服务,引入justauth-spring-boot-starter直接在配置文件中定义好第一步的三个参数,并提供获取登录页面的接口和回调…...
Amcor 如何借助 Liquid UI 实现SAP PM可靠性
背景介绍 安姆科是塑料行业的全球领军企业,该企业认识到 SAP 工厂维护(SAP PM)对于确保高效的维护管理的重要性。 在诸如制造业等高度依赖机械设备的行业中,SAP PM是一种通过数据驱动决策来最大限度减少停机时间、降低间接成本、…...
【Redis】常见基本全局命令
一、Redis俩大核心命令 由于Redis是以键值对的形式进行数据存取,自然就离不开不断的存储和获取,而其所对应的命令则是set和get,如此说来二者为Redis的核心基础命令也不为过。 作用:用于存储Stirng类型的数据 返回:当…...
探索国际数据空间(IDS)架构(上)
在当今数字化时代,数据的重要性日益凸显,而国际数据空间(IDS)作为一个新兴的概念,正逐渐成为数据管理和共享的关键领域。今天,我们就来一起探索一下 IDS 的精妙架构。 参考文章:国际数据空间&am…...
如何选择好用的U盘数据恢复软件免费版?2024年热门榜单有哪些?
U盘是我们用来存数据的小玩意儿,又方便又好用。但是,有时候因为不小心删掉了、格式化了或者中病毒了,U盘里的东西就没了,这可让人头疼。好在有很多免费的U盘数据恢复软件能帮我们找回这些丢失的数据。那怎么挑一个好用的免费数据恢…...
音视频入门基础:AAC专题(12)——FFmpeg源码中,解码AudioSpecificConfig的实现
音视频入门基础:AAC专题系列文章: 音视频入门基础:AAC专题(1)——AAC官方文档下载 音视频入门基础:AAC专题(2)——使用FFmpeg命令生成AAC裸流文件 音视频入门基础:AAC…...
UDP组播测试
支持组播的接口: ip a | grep MULTICAST 环回接口虽然显示不支持组播,实际也可以用于本地测试。 添加路由(非必须?): ip route add 239.0.0.0/24 via 10.10.10.206 dev eth0 开放防火墙: 查…...
【Nas】X-Doc:jellyfin“该客户端与媒体不兼容,服务器未发送兼容的媒体格式”问题解决方案
【Nas】X-Doc:jellyfin“该客户端与媒体不兼容,服务器未发送兼容的媒体格式”问题解决方案 当使用Jellyfin播放视频时出现“该客户端与媒体不兼容,服务器未发送兼容的媒体格式”,这是与硬件解码和ffmpeg设置有关系,具体…...
504 Gateway Time-outopenresty
504 Gateway Time-out openresty 问题背景: 当自己点开知乎页面以后,发现官网没有出现任何问题,点击官网以后开始出现各种各样的报错! 一下是来源ai的介绍:(通过搜索这种形式帮助自己进行记忆)…...
SpringBoot篇(自动装配原理)
目录 一、自动装配机制 1. 简介 2. 自动装配主要依靠三个核心的关键技术 3. run()方法加载启动类 4. 注解SpringBootApplication包含了多个注解 4.1 SpringBootConfiguration 4.2 ComponentScan 4.3 EnableAutoConfiguration 5. SpringBootApplication一共做了三件事 …...
《Web性能权威指南》-WebRTC-读书笔记
本文是《Web性能权威指南》第四部分——WebRTC的读书笔记。 第一部分——网络技术概览,请参考网络技术概览; 第二部分——无线网络性能,请参考无线网络性能; 第三部分——HTTP,请参考HTTP; 第四部分——浏览…...
跨境电商独立站:打造你的全球品牌
什么是跨境电商独立站? 跨境电商独立站是指一个独立的电子商务网站,企业可以通过这个网站直接向全球消费者销售产品。与入驻亚马逊、eBay等第三方平台不同,独立站拥有完全自主权,可以自由定制店铺风格、营销策略,并直…...
基于uniapp微信小程序的旅游系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…...
怿星科技薛春宇丨智能汽车软件研发工具链国产化的挑战和探索
2024年7月25日,由上海良益企业管理咨询有限公司主办的“2024域控制器技术论坛“在上海成功举办,十位嘉宾做了精彩分享。“整零有道”将陆续刊出部分演讲的文字实录,以飨读者。 本期刊出怿星科技副总经理薛春宇的演讲实录:智能汽车…...
Flutter动画渐变
User experience is everything. One way to improve it is by making transitions between different UI elements smoother and more visually appealing. This is where the AnimatedCrossFade widget comes in handy. 用户体验就是一切。改善用户体验的方法之一就是让不同…...
Python毕业设计选题:基于Web学生会网站的设计与实现-django
开发语言:Python框架:djangoPython版本:python3.7.7数据库:mysql 5.7数据库工具:Navicat11开发软件:PyCharm 系统展示 系统首页界面 用户注册界面 用户登录界面 校内报道界面 品牌活动界面 个人中心界面 …...
如何选购高性价比百元头戴式耳机?六大选购技巧加性价比耳机推荐
在日益繁忙的生活中,头戴式耳机已成为许多人享受音乐、放松心情的重要工具。然而,市面上的头戴式耳机种类繁多,价格各异,如何选购高性价比百元头戴式耳机?成为了许多消费者的难题。为了帮助大家更好地做出选择…...
Java爬虫的京东“寻宝记”:揭秘商品类目信息
开篇:Java特工的神秘任务 在这个数据驱动的时代,我们就像一群特工,穿梭在数字的海洋中,寻找着隐藏的宝藏——商品类目信息。今天,我们将带领你一起,用Java这把精密的瑞士军刀,深入京东的神秘领…...
React前端框架
React 是一个用于构建用户界面的 JavaScript 库,由 Facebook 开发和维护。React 采用组件化的开发方式,使得开发者可以构建可复用的 UI 组件,从而提高开发效率和代码的可维护性。 React 的基本概念 组件:React 的核心概念是组件…...
React-query vs. 神秘新工具:前端开发的新较量
流畅的分页体验:AlovaJS的分页请求策略 在现代web应用中,分页是一个常见的功能需求。无论是浏览商品列表、查看文章集合,还是管理后台的数据表格,用户都需要一种高效且流畅的方式来浏览大量数据。然而,实现一个流畅且…...
TensorFlow面试整理-分布式
在深度学习的训练过程中,随着数据量和模型的复杂性增加,单个 GPU 或 CPU 无法满足高效训练的需求。TensorFlow 提供了强大的 分布式训练 功能,通过并行处理加速训练过程。分布式训练可以在多个 GPU、多个机器甚至是 TPU 上运行。以下是分布式训练的关键概念及其使用方法。 1…...
OceanBase 回收站机制详解
OceanBase 回收站机制详解 在 OceanBase 数据库中,回收站机制用于在执行 DROP 或 TRUNCATE 等操作后,临时保存被删除的对象,以便在需要时进行恢复。以下是对回收站机制的详细说明: 1. 不同租户对回收站的访问权限 SYS 租户 权…...
Java特工队:潜入京东,高效获取商品详情的绝密行动
在这个由代码和逻辑编织的电商世界里,京东商品详情就像是被锁在高塔中的神秘卷轴,等待着勇敢的Java特工队成员去解救。今天,我们要讲述的是如何装备你的Java代码装备,化身为一名编程界的特工,潜入京东的API网络&#x…...
车易泊相机 —— 智能车位管理的得力助手
在当今社会,停车问题日益成为城市管理和人们日常生活中的一大难题。寻找车位耗费时间、车位被非法占用、停车管理效率低下等问题层出不穷。然而,车易泊相机的出现,为车位管理带来了全新的解决方案。 一、车易泊相机的强大功能 车易泊相机是一…...
C++初阶(七)--类和对象(4)
目录 编辑 一、再谈构造函数 1.构造函数体赋值 2.初始化列表 二、类型转换 1.隐式类型转换 2.explicit关键字 3.类类型之间的对象隐式转换 三、static成员函数 1.概念 2.特性 3.面试题: 四、友元函数 1.基本介绍 2.回顾: 3.友元类&am…...
Python 爬虫的寻宝大冒险:如何捕获 API 数据的宝藏
在这个信息爆炸的数字时代,数据就像是隐藏在网络深处的宝藏,等待着勇敢的探险家去发现。今天,我们要讲述的是如何成为一名 Python 爬虫探险家,装备你的代码工具,深入 API 的迷宫,捕获那些珍贵的数据宝藏。 …...
网站整体结构/深圳英文网站推广
AspAccess的程序在NTFS分区上常常出现这样那样的问题,这切都是安全权限惹的祸,所以要想正常调试一个网站还需要更详细的设置。1.安装IIS7右单击的桌面上的[计算机]》选择[管理]扩展[角色]展卷栏》单击[添加角色]》在[添加角色向导]对话框中选择[Web服务器…...
网站编辑转行做文案/软件培训
前言 很多朋友问我的博客是什么软件写的,嘻嘻,其潜台词是我的博客页面还挺好看的呢!!!心里美滋滋的,这里就把方法共享出来吧 定制样式而已 我的博客主要是对H1的样式做了一点改变,给H1加上了背景…...
学院招生网站建设方案/临沂百度推广多少钱
给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。 完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。 …...
做网站什么分类流量多/西安seo王尘宇
axios用多了就开始疑惑它里面到底是个啥,虽然总被告知它就是基于ajax的封装,但掐指一算,事情应该没这么简单,于是开始深挖,挖着挖着就挖到了Promise。毕竟axios的官方描述是这样的:Promise based HTTP clie…...
网站建设 开办费/上海公司排名
本人应用PHP开发程序也小有年头了,对于PHP程序也有一些自己的简介,接触了一些国内外优秀的MVC框架,近日,突然想了解一下基本的MVC框架式如何实现的,所以开始着手研究自己动手打造出一个简单的MVC框架。对于研究的心得拿…...
昆明网站建设-中国互联/百度助手应用商店下载安装
这篇文章主要介绍了PhpstormXdebug断点调试PHP的方法,本教程将通过配置Xdebug扩展进行断点调试,目的在于提高大家的开发效率,感兴趣的小伙伴们可以参考一下为什么使用断点调试大家可能会觉得使用var_dump和echo也能调试啊,为什么还…...