引言

设计模式是前端工程化架构的基石,通过抽象核心场景解法提升代码复用性与系统可维护性。本文精析 7 个核心模式,结合原生 JavaScript 与框架实践,揭示模式在现代前端架构中的底层映射与应用。


1. 观察者模式(Observer)

核心思想:状态变更自动通知依赖对象,实现发布-订阅解耦机制。

技术演进:从原生事件系统到响应式框架状态管理。

// 原生实现(明确订阅-通知生命周期)
class Observable {constructor() { this.observers = []; }subscribe(fn) { this.observers.push(fn); }  // 显式订阅unsubscribe(fn) { /* 移除逻辑 */ }          // 防止内存泄漏notify(data) {                              // 广播状态变更this.observers.forEach(observer => observer(data));}
}// 框架映射说明:
// - Vue reactive():基于 Proxy 实现细粒度依赖追踪
// - React useState():状态调度机制(非传统观察者),依赖 Fiber 架构批量更新

关键区分:原生观察者需显式管理订阅关系,而框架通过虚拟 DOM/响应式代理自动处理依赖。


2. 策略模式(Strategy)

核心思想:封装可互换算法族,运行时动态切换策略。

扩展场景:动态表单校验规则、多端渲染策略适配(Web/Mobile)。

// 多策略组合验证(支持异步)
const validationStrategies = {email: async (value) => { /* API 验证 */ },password: (value) => /[A-Z]/.test(value)  // 包含大写字母
};class Validator {constructor(strategies) {this.strategies = strategies;this.errors = [];}async validate(key, value) {const result = await this.strategies[key](value);if (!result) this.errors.push(`${key}验证失败`);}
}

工业实践:Webpack 的 loader 链本质是策略管道,Vite 插件系统采用策略组合扩展编译行为。


3. 装饰器模式(Decorator)

核心思想:通过包装器增强功能,遵循开放封闭原则。

技术深化:AOP(面向切面编程)实现日志/性能埋点。

// TypeScript 方法装饰器(性能分析切面)
function logPerf(_: any, name: string, descriptor: PropertyDescriptor) {const original = descriptor.value;descriptor.value = function(...args) {const start = performance.now();const result = original.apply(this, args);console.log(`${name}执行耗时: ${performance.now() - start}ms`);return result;};
}class API {@logPerffetchData() { /* 网络请求 */ }
}

框架约束:React HOC 需遵守 displayName 规范,避免 DevTools 调试混淆。


4. 单例模式(Singleton)

核心思想:确保类唯一实例,全局共享状态/服务。

前端场景:全局状态管理、浏览器存储代理、WebSocket 连接池。

class AuthService {  // 单例身份验证服务static instance;static getInstance() {if (!AuthService.instance) {AuthService.instance = new AuthService();}return AuthService.instance;}constructor() {this.token = localStorage.getItem('token');}login(token) { this.token = token;// 广播登录事件(结合观察者)}
}// 全应用统一访问点
const auth = AuthService.getInstance();

风险提示:单例模块化需考虑服务注销机制,避免 SPA 路由切换后状态残留。


5. 命令模式(Command)

核心思想:将操作封装为对象,支持撤销/重做与事务管理。

前端场景:操作历史栈、批量任务调度、UI 动作解耦。

// 可撤销的 Canvas 绘图命令
class DrawCommand {constructor(canvas, params) {this.canvas = canvas;this.params = params;this.prevState = canvas.getState();  // 保存前一状态}execute() {this.canvas.draw(this.params);}undo() {this.canvas.restore(this.prevState);  // 恢复历史状态}
}// 命令管理器(支持事务)
class CommandManager {history = [];invoke(command) {command.execute();this.history.push(command);}undo() {const cmd = this.history.pop();cmd?.undo();}
}

应用实例:富文本编辑器操作历史、Redux 的 Action 命令化分发。


6. 代理模式(Proxy)

核心思想:中介对象控制访问,实现缓存/验证/懒加载。

性能优化:API 请求智能缓存代理。

const apiCache = new Map();const apiProxy = new Proxy(fetch, {  // 拦截 fetchasync apply(target, _, args) {const [url] = args;if (apiCache.has(url)) return apiCache.get(url);  // 返回缓存const res = await target(...args);                // 执行真实请求apiCache.set(url, res);return res;}
});// 使用代理后的 fetch
apiProxy('/data').then(...);

陷阱规避:Proxy 嵌套对象需递归代理,避免部分属性未拦截。


7. 组合模式(Composite)

核心思想:统一处理树状结构,抽象部分-整体关系。

现代演进:微前端架构中的应用模块树。

// 插件系统组合(支持嵌套注册)
const PluginSystem = ({ children }) => {useEffect(() => {// 递归初始化所有子插件React.Children.forEach(children, plugin => plugin.init?.());}, []);return <>{children}</>;
};<PluginSystem><AnalyticsPlugin /><PluginSystem>  {/* 嵌套组合 */}<SecurityPlugin /></PluginSystem>
</PluginSystem>

设计模式的应用

前端框架演进史本质是设计模式的融合实践。解耦艺术通过观察者模式将视图层与数据流分离(如 Vue 的响应式系统),而控制反转在工厂模式中体现为组件创建权移交框架(React 的 ReactDOM.createRoot)。单例模式实现全局状态共享(Redux store),却需警惕违反迪米特法则引发的隐式耦合。

在复杂交互场景,命令模式与策略模式的协同构成可撤销操作流水线:

  1. 用户动作封装为命令对象(Command)

  2. 命令管理器按策略模式选择执行/存储方案

  3. 代理模式拦截命令执行,注入性能监控

当代架构趋势如 React Server Components,本质是策略模式(渲染位置决策)、代理模式(服务端-客户端组件桥接)与组合模式的深度融合。掌握模式内核,方能设计出 高内聚低耦合 的前端系统。

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

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

相关文章

【机器学习深度学习】Ollama vs vLLM vs LMDeploy:三大本地部署框架深度对比解析

目录 前言 一、为什么要本地部署大语言模型&#xff1f; 二、三大主流部署方案简介 三、核心对比维度详解 1️⃣ 易用性对比 2️⃣ 性能与并发能力 3️⃣ 模型支持与生态兼容性 4️⃣ 部署环境与平台支持 四、一览对比表 五、详细介绍与比较 ✅ 1. Ollama ✅ 2. vL…

AWS ML Specialist 考试备考指南

以下是针对AWS机器学习专家认证(AWS Certified Machine Learning - Specialty)的备考指南精简版,涵盖核心要点和高效备考策略: ‌一、考试核心要点‌ ‌四大核心领域‌: ‌数据准备(28%)‌:S3数据存储、Glue ETL、Feature Store、数据清洗与特征工程。 ‌模型开发(26%…

yolo8+ASR+NLP+TTS(视觉语音助手)

&#x1f9e9; 模块总览&#xff1a;步骤模块作用①麦克风录音&#xff08;VAD支持&#xff09;获取语音并判断是否有人说话②Whisper语音识别把语音内容识别为文字③DeepSeek 聊天接口发送用户提问并获取 AI 回复④edge-tts 朗读回答把 DeepSeek 回答读出来⑤整合成语音助手主…

Zabbix 分布式监控系统架构设计与优化

一、概念 1.核心概念 Zabbix是一个CS(服务端/客户端)架构的服务Zabbix-Agent获取数据-->发送给-->Zabbix-Server服务端--- >数据会被存放在数据库 <--- Zabbix Web 页面展示数据 2.部署流程 部署ngxphp环境并测试部署数据库 mariadb 10.5及以上 然后进行配置编…

QT——文件选择对话框 QFileDialog

QFileDialog概述QFileDialog是Qt框架中提供的文件对话框类&#xff0c;用于让用户选择文件或目录。它提供了标准的文件选择界面&#xff0c;支持文件打开、保存、多选等常见操作。基本使用方式QFileDialog提供了两种使用方式&#xff1a;静态方法&#xff1a;直接调用类方法快速…

Flask+LayUI开发手记(十一):选项集合的数据库扩展类

条目较少的选项集合&#xff0c;确实可以在程序中直接定义&#xff08;其实最合适的还是存储在一个分类别的数据库表里&#xff09;&#xff0c;但条目较多的选项集合&#xff0c;或者是复杂的树型结构选项集合&#xff0c;一般都是存储在数据库中的&#xff0c;这样维护起来比…

AI学习笔记三十二:YOLOv8-CPP-Inference测试(Linux版本)

若该文为原创文章&#xff0c;转载请注明原文出处。主要介绍如何在Linux系统上安装和部署基于YOLOv8的C推理项目一、服务器准备使用AutoDL平台租用服务器AutoDL有git加速&#xff0c;可以自行启用二、环境配件1、检查Opencv版本pkg-config --modversion opencv4如果版本为4.5&a…

113:路径总和 II

题目&#xff1a;给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。叶子节点 是指没有子节点的节点。解答&#xff1a;用 go主要坑有两个&#xff0c;一个是二维结果切片传递用指针&#xff0c;一个…

Perl 数组

Perl 数组 在Perl编程语言中&#xff0c;数组是处理数据的一种强大工具。数组允许我们将多个值存储在单个变量中&#xff0c;从而简化了代码并提高了效率。本文将详细介绍Perl数组的创建、操作、遍历以及一些高级用法。 数组的创建 在Perl中&#xff0c;创建一个数组非常简单。…

优先队列的实现

目录 引言 堆的基本概念与特性 堆的插入与向上调整 堆的删除与向下调整 优先队列的设计思路 模板参数设计 比较器的作用 核心接口实现 push pop top 附录(完整代码) 引言 优先队列&#xff08;Priority Queue&#xff09;是一种特殊的队列数据结构&#xff0c;其中每…

现代CSS实战:用变量与嵌套重构可维护的前端样式

现代CSS实战&#xff1a;用变量与嵌套重构可维护的前端样式 引言 在传统CSS开发中&#xff0c;我们常常陷入「样式冗余」与「维护噩梦」的循环&#xff1a; 想调整主题色&#xff1f;得全局搜索所有 #3498db 手动替换&#xff0c;稍有不慎就漏改某个角落&#xff1b; 写嵌套…

DHTMLX Suite 9.2 重磅发布:支持历史记录、类Excel交互、剪贴板、拖放增强等多项升级

全球知名的 JavaScript UI 组件库 DHTMLX Suite 迎来 9.2 新版本&#xff01;此次更新虽为次版本号&#xff0c;却实质性提升了 Grid 网格组件的交互能力与用户体验&#xff0c;引入了包括历史记录管理、剪贴板操作、数据选择范围管理、Block 区块选择等多项高级模块&#xff0…

深入理解Java中的Map.Entry接口

文章目录深入理解Java中的Map.Entry接口1. 接口定义2. 核心方法解析2.1 基本方法2.2 Java 8新增的静态方法3. 基本使用示例3.1 遍历Map的条目3.2 修改Map中的值3.3 使用比较器排序4. Java 8/9增强特性4.1 与Stream API结合4.2 Java 9的equals和hashCode默认方法5. 实际应用场景…

AI培训学习2

不要打扰用户的习惯&#xff0c;比如APP右下角的我的&#xff0c;放到第一个就不合适 先抄再超 lifeTime value NPS: 评价 Product market 平衡 ARPU&#xff1a; LT活跃时长 游戏中好友的重要性 不花钱存活率很少 如何花钱&#xff0c;1分钱买东西 联影医疗 figma uizard…

npm 安装时候怎么指定某一个子包的版本 overrides

有时候用 npm install 安装的时候会报错&#xff0c;比如 express 包依赖 "escape-html": "^1.0.2" 版本的包&#xff0c;但是因为 escape-html" 升级到 1.0.3 版本了&#xff0c;但是这个版本有问题&#xff0c;导致express 下载不下来。怎么固定下载…

python学智能算法(十九)|SVM基础概念-超平面

引言 前序学习进程中&#xff0c;对向量相关的基本知识进行了学习&#xff0c;链接为&#xff1a; 向量的值和方向 向量点积 在实际的支持向量机算法使用中&#xff0c;最核心的目标是找出可以实现分类的超平面&#xff0c;超平面就是分割的点、线或者面&#xff0c;不要在这个…

python 基于 httpx 的流式请求

文章目录1. 环境介绍2. 同步客户端2.1. 面向过程2.1.1. 流式输出2.1.2. 非流式输出2.2. 面向对象3. 异步客户端3.1. 面向过程3.2. 面向对象3.3. Attempted to call a sync iterator on an async stream.参考&#xff1a;https://www.jb51.net/article/262636.htm次要参考&#…

Python 数据建模与分析项目实战预备 Day 4 - EDA(探索性数据分析)与可视化

✅ 今日目标 使用 Pandas Matplotlib/Seaborn 对简历数据进行探索性分析分析不同字段与目标变量的相关性通过可视化呈现简历筛选的潜在规律&#x1f9fe; 一、建议分析内容 &#x1f539; 分类字段分析字段图表建议说明degree柱状图&#xff08;分组通过率&#xff09;分析学历…

力扣每日一题--2025.7.17

&#x1f4da; 力扣每日一题–2025.7.17 &#x1f4da; 3202. 找出有效子序列的最大长度 II&#xff08;中等&#xff09; 今天我们要解决的是力扣上的第 3202 题——找出有效子序列的最大长度 II。这道题是昨天 3201 题的扩展&#xff0c;需要我们处理更一般化的情况。 ⚠️…

github不能访问怎么办

访问&#xff1a;“github.com”国内多个地点网站测速结果_网站测速 - 站长工具访问“github.global.ssl.fastly.net”国内多个地点网站测速结果_网站测速 - 站长工具复制红框中的ip 打开“C:\Windows\System32\drivers\etc\hosts”文件输入&#xff1a; 20.205.243.166 githu…