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

前端开发的观察者模式

什么是观察者设计模式

观察者模式(Observer Pattern)是前端开发中常用的一种设计模式。它定义了一种一对多的依赖关系,使得当一个对象的状态发生改变时,其所有依赖对象都能收到通知并自动更新。观察者模式广泛应用于事件驱动的系统,如浏览器事件、发布-订阅系统,以及各类框架的状态管理机制。

观察者设计模式定义了一种 一对多 的依赖关系,当 一个对象的状态发生变化 时,所有依赖它的对象都会自动收到通知。这种模式可以解耦观察者和被观察者,使得它们可以独立变化。

观察者模式的关键角色:

  1. Subject(被观察者): 负责维护观察者列表,并在自身状态发生变化时通知所有观察者。
  2. Observer(观察者): 订阅目标的变化,并在收到通知时执行相关操作。

观察者模式的实现

1. 简单观察者模式

// 观察者接口
interface Observer {update(state: string): void;
}// 被观察者
class Subject {private observers: Observer[] = [];private state: string = '';// 添加观察者public attach(observer: Observer): void {this.observers.push(observer);}// 移除观察者public detach(observer: Observer): void {this.observers = this.observers.filter(obs => obs !== observer);}// 通知所有观察者public notify(): void {this.observers.forEach(observer => observer.update(this.state));}// 改变状态并通知观察者public setState(state: string): void {this.state = state;this.notify();}
}// 具体的观察者
class ConcreteObserver implements Observer {private name: string;constructor(name: string) {this.name = name;}// 收到通知时的动作public update(state: string): void {console.log(`${this.name} received update: ${state}`);}
}// 测试观察者模式
const subject = new Subject();const observer1 = new ConcreteObserver('Observer 1');
const observer2 = new ConcreteObserver('Observer 2');subject.attach(observer1);
subject.attach(observer2);subject.setState('State A');
subject.setState('State B');

在这个例子中,我们实现了基本的观察者模式:一个 Subject 类可以被多个 Observer 观察,每当 Subject 的状态发生变化时,它会通知所有观察者。

2. 发布-订阅模式

发布-订阅模式(Publish-Subscribe Pattern) 是观察者模式的一种变体,通常通过事件系统来实现。发布者不直接通知观察者,而是通过中介(消息中心)将事件广播出去,由订阅者选择性地接收。

// 消息中心
class EventEmitter {private events: { [key: string]: Function[] } = {};// 订阅事件public subscribe(event: string, listener: Function): void {if (!this.events[event]) {this.events[event] = [];}this.events[event].push(listener);}// 发布事件public publish(event: string, data?: any): void {if (this.events[event]) {this.events[event].forEach(listener => listener(data));}}// 取消订阅public unsubscribe(event: string, listener: Function): void {if (this.events[event]) {this.events[event] = this.events[event].filter(l => l !== listener);}}
}// 测试发布-订阅模式
const eventEmitter = new EventEmitter();const handler = (data: any) => console.log('Event received:', data);// 订阅事件
eventEmitter.subscribe('eventA', handler);// 发布事件
eventEmitter.publish('eventA', { message: 'Hello, World!' });// 取消订阅
eventEmitter.unsubscribe('eventA', handler);

在发布-订阅模式中,发布者和订阅者是通过 EventEmitter 消息中心进行通信的,发布者无需知道订阅者的存在,这使得它们之间的耦合度进一步降低。

3. 双向绑定模式(MVVM)

MVVM(Model-View-ViewModel) 是一种常见的双向绑定模式,在前端框架如 VueAngular 中很常见。它通过数据绑定使得 ViewModel 可以双向通信,通常是通过一个 ViewModel 来桥接二者。

// ViewModel
class ViewModel {private state: string = '';private observers: Function[] = [];// 获取当前状态public getState(): string {return this.state;}// 设置状态并通知视图更新public setState(newState: string): void {this.state = newState;this.notify();}// 添加视图更新的回调public bind(observer: Function): void {this.observers.push(observer);}// 通知视图更新private notify(): void {this.observers.forEach(observer => observer(this.state));}
}// 视图更新函数
const updateView = (state: string) => {console.log('View updated:', state);
};// 测试双向绑定
const viewModel = new ViewModel();
viewModel.bind(updateView);viewModel.setState('New State');
console.log('Current State:', viewModel.getState());

在这个例子中,ViewModel 充当了模型和视图之间的桥梁,确保视图在数据更新时及时反应。这是 MVVM 模式的一个简单实现。

总结

观察者设计模式及其变体在前端开发中起着至关重要的作用。通过观察者模式,可以解耦对象之间的直接依赖关系,从而提升系统的灵活性和可维护性。无论是基础的观察者模式,还是更为复杂的发布-订阅模式、双向绑定模式,都在不同的场景中发挥了不可替代的作用。

 

相关文章:

前端开发的观察者模式

什么是观察者设计模式 观察者模式(Observer Pattern)是前端开发中常用的一种设计模式。它定义了一种一对多的依赖关系,使得当一个对象的状态发生改变时,其所有依赖对象都能收到通知并自动更新。观察者模式广泛应用于事件驱动的系…...

Pycharm 输入三个引号没有自动生成函数(方法)注释

配置项路径:pycharm–>Settins–>Tools–>Python Integrated Tools–>Docstrings–>Docstrings format选择对应的工程,如果有多个工程的话将 Docstrings format 的值从 Plain 换成 reStructuredText...

lammps后处理:多帧孔洞体积和孔隙率的计算

本文介绍lammps后处理技巧:多帧孔洞体积和孔隙率的计算方法。 在前面的专栏中,已经介绍了单帧孔洞体积的计算方法,有不少粉丝朋友咨询多帧孔洞体积的计算方法。 在上一次案例代码的基础上,稍加修改,添加一个for循环遍历所有的帧即可实现多帧孔洞体积的计算。 计算的结果…...

免费且实用:UI设计常用的颜色参考网站和一些Icon设计网站

用心去分享!请给我点个关注和点赞收藏!谢谢各位努力的人才! 1.在UI设计的时候,没有灵感,怎么办?可以参考这个网站(需要魔法能量) 网址如下: Color Hunt - Color Palette…...

log4j日志封装说明—slf4j对于log4j的日志封装-正确获取调用堆栈

日志是项目中必用的东西,日志产品里最普及应该就是log4j了。(logback这里暂不讨论。) 先看一下常用的log4j的用法,一般来说log4j都会配合slf4j或者common-logging使用,这里已slf4j为例。添加gradle依赖: dependencies { compile(l…...

JVM面试真题总结(六)

文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 解释GC的标记-整理算法及其优点 GC(垃圾收集&#xff…...

C语言代码练习(第十八天)

今日练习: 48、猴子吃桃问题。猴子第1天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第2天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时&…...

linux上使用rpm的方式安装mysql

1.从mysql官网上下载需要的版本,根据操作系统版本,CPU架构,下载让rpm bundle,这个版本是个完整版,包含其他所有版本 上传到服务器的一个目录,进行解压 执行tar -xvf mysql*.tar tar -xvf mysql*.tar 2.卸载老版本m…...

html 中如何使用 uniapp 的部分方法

示例代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><…...

Samtec连接器小课堂 | 连接器电镀常识QA

【摘要/前言】 像大多数电子元件一样&#xff0c;无数子元件和工艺的质量直接影响到成品的质量和性能。对于PCB级连接器&#xff0c;这些因素包括针脚材料、塑料类型、模制塑料体的质量、尾部的共面性、表面处理&#xff08;电镀&#xff09;的质量、选择正确的连接器电镀、制…...

大模型备案全网最详细流程解读(附附件+重点解读)

文章目录 一、语料安全评估 二、黑盒测试 三、模型安全措施评估 四、性能评估 五、性能评估 六、安全性评估 七、可解释性评估 八、法律和合规性评估 九、应急管理措施 十、材料准备 十一、【线下流程】大模型备案线下详细步骤说明 十二、【线上流程】算法备案填报…...

基于2143规则编码的uint8_t如何转换成float

2143格式存储的float类型数据在解码时&#xff0c;需要将1和2互换&#xff0c;3和4互换&#xff0c;然后 通过数组转float&#xff0c;进行转换 uint8_t data[] {0x72, 0x02, 0xc8, 0x42}; // 字节数组 float bytesToFloat(uint8_t data[]) { uint32_t x; memcpy(&x, da…...

[项目][WebServer][整体框架设计]详细讲解

目录 0.框架 && 前言1.TcpServer类1.功能2.类设计 2.HttpServer类1.功能2.类设计 3.Request类 && Response类1.功能2.Request类设计3.Response类设计 4.EndPoint类1.功能2.类设计 5.Task类1.功能2.类设计 6.ThreadPool类1.功能2.类设计 0.框架 && 前言…...

SprinBoot+Vue网上购物商城的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平台Java领域优质…...

【数据结构】2——二叉树遍历

数据结构2——二叉树遍历 单纯记录 文章目录 数据结构2——二叉树遍历一、二叉树遍历1&#xff0c;先序遍历&#xff1a;根左右递归实现非递归实现&#xff08;栈&#xff09; 2.中序遍历&#xff1a;左根右递归非递归 3 .后序遍历&#xff1a;左右根递归非递归&#xff08;两…...

数据结构应用实例(五)——关键路径

Content: 一、问题描述二、算法思想三、代码实现四、小结 一、问题描述 设计实现 AOE 网的关键活动与关键路径问题&#xff1b; 二、算法思想 获取拓扑序列&#xff1b;计算节点的最早开始时间 v e [ i ] ve[i] ve[i]&#xff1b;计算节点的最晚开始时间 v l [ j ] vl[j] v…...

组播 2024 9 11

PIM&#xff08;Protocol Independent Multicast&#xff09;是一种常用的组播路由协议&#xff0c;其独立于底层的单播路由协议&#xff0c;能够在多种网络环境中有效地实现多播路由功能。PIM主要有两种模式&#xff1a;PIM Sparse Mode (PIM-SM) 和 PIM Dense Mode (PIM-DM)&…...

揭秘开发者的效率倍增器:编程工具的选择与应用

文章目录 每日一句正能量前言工具介绍功能特点&#xff1a;使用场景&#xff1a;提高工作效率的方式&#xff1a; 效率对比未来趋势后记 每日一句正能量 这推开心窗之人&#xff0c;可以是亲朋好友&#xff0c;也可以是陌客路人&#xff0c;可以是德高望重的哲人名流&#xff0…...

在AI的时代,程序员如何才不被淘汰

随着人工智能技术的迅猛发展&#xff0c;大模型&#xff08;Large Language Models, LLMs&#xff09;正逐渐成为IT行业的热点。对于程序员来说&#xff0c;转行大模型领域不仅意味着新的机遇&#xff0c;也面临着诸多挑战。本文将探讨程序员转行大模型的机遇与挑战&#xff0c…...

tabBar设置底部菜单选项以及iconfont图标,setTabBar设置TabBar和下拉刷新API

tabBartabBar属性:设置底部 tab 的表现 ​ ​ ​ ​ 首先在pages.json页面写一个tabBar对象,里面放入list对象数组,里面至少要有2个、最多5个 tab, 如果只有一个tab的话,H5(浏览器)依然可以显示底部有一个导航栏,如果没有,需要重启后才有,小程序则报错,只有2个以上才可以…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...