JS 高级程序设计 设计模式
- 设计模式是提升代码可维护性、可扩展性和可复用的重要工具
创建型模式
工厂模式
- 封装对象的创建过程,通过函数或类统一生成实例,避免直接使用 new 关键字
- 简单工厂:通过函数返回不同对象实例
function createButton(type) {if (type === 'primary') return { color: 'blue' };else if (type === 'danger') return { color: 'red' };
}示例2
class Circle { draw() { console.log('Draw Circle'); } }
class Square { draw() { console.log('Draw Square'); } }class ShapeFactory {static create(type) {switch(type) {case 'circle': return new Circle();case 'square': return new Square();default: throw new Error('Unknown shape');}}
}const shape1 = ShapeFactory.create('circle');
shape1.draw(); // Draw Circle
- 应用场景:组件库(如根据类型生成不同 UI 组件
抽象工厂模式
抽象工厂提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定其具体类。
TutorialsPoint 适合需要同时创建多个具有同一主题的产品族时,例如皮肤主题下按钮、输入框、弹窗的统一创建
// 抽象产品接口
class Button { render() {} }
class Modal { open() {} }// 具体产品:Light 主题
class LightButton extends Button { render() { console.log('Light Button'); } }
class LightModal extends Modal { open() { console.log('Light Modal'); } }// 抽象工厂接口
class UIAbstractFactory {createButton() {}createModal() {}
}// 具体工厂:Light
class LightFactory extends UIAbstractFactory {createButton() { return new LightButton(); }createModal() { return new LightModal(); }
}// 客户端
function initUI(factory) {const btn = factory.createButton();const modal = factory.createModal();btn.render(); modal.open();
}
initUI(new LightFactory());
- 通过替换工厂即可切换整套 UI 产品族
单例模式
- 单例模式确保一个类只有一个实例,并提供全局访问点。GeeksforGeeks适用于需要全局唯一配置或管理器的场景,如日志管理、缓存管理等
class Singleton {constructor(value) {if (Singleton.instance) {return Singleton.instance;}this.value = value;Singleton.instance = this;}
}
const a = new Singleton(1);
const b = new Singleton(2);
console.log(a === b, a.value, b.value); // true, 1, 1
原型模式
- 原型模式使用已有对象作为原型,通过复制来创建新对象,从而减少新建对象的性能开销。重构大师适用于大量相似对象的场景,如动画游戏中重复出现的敌机实例
const prototypeObject = {init(name) { this.name = name; },clone() { return Object.create(this); }
};const obj1 = prototypeObject.clone();
obj1.init('Alice');
console.log(obj1.name); // Aliceconst obj2 = prototypeObject.clone();
obj2.init('Bob');
console.log(obj2.name); // Bob
结构型模式
模块模式
- 模块模式利用闭包创建私有变量和方法,只暴露公共接口,实现封装和命名空间管理。TutorialsPoint常见于前端脚本组织,如将 API 调用逻辑封装在独立模块中
const CounterModule = (function() {let count = 0; // 私有return {increment() { count++; },getCount() { return count; }};
})();
CounterModule.increment();
console.log(CounterModule.getCount()); // 1
私有变量 count 只能通过暴露的方法访问,避免全局污染
装饰器模式
- 装饰器模式在不修改原有对象结构的前提下,动态地给对象添加职责或行为
- 适用于功能扩展,比如给函数添加日志、缓存或权限校验功能
function basicLogging(fn) {return function(...args) {console.log('Input:', args);const result = fn(...args);console.log('Output:', result);return result;};
}function add(a, b) { return a + b; }
const loggedAdd = basicLogging(add);
loggedAdd(2, 3); // 日志 + 返回 5
用高阶函数包装原函数,实现“装饰”效果
外观模式
- 外观模式为复杂子系统提供统一、简化的接口,屏蔽内部复杂性
- 例如为浏览器的多种网络请求方式(XHR、fetch)提供统一调用入口。
const HttpFacade = {get(url) { return fetch(url).then(res => res.json()); },post(url, data) { return fetch(url, {method: 'POST',headers: {'Content-Type':'application/json'},body: JSON.stringify(data)}).then(res => res.json());}
};
HttpFacade.get('/api/data').then(console.log);
客户端无需关心底层实现细节
行为型模式
观察者模式
- 观察者模式定义对象间一对多的依赖,当目标对象状态改变时,自动通知所有观察者
- 适用于事件驱动或发布/订阅场景,如浏览器事件、MVC 中的模型-视图更新。
class Subject {constructor() { this.observers = []; }subscribe(o) { this.observers.push(o); }unsubscribe(o) { this.observers = this.observers.filter(obs => obs !== o); }notify(data) { this.observers.forEach(obs => obs.update(data)); }
}
class Observer {update(data) { console.log('Received:', data); }
}
const subj = new Subject();
const obs = new Observer();
subj.subscribe(obs);
subj.notify('Hello'); // Observers 收到通知
策略模式
- 策略模式定义一系列算法,将每个算法封装成独立策略类,并使它们可以互换
- 适用于需在多种算法间切换的场景,如不同排序、不同折扣计算方式
const strategies = {bubble: arr => { /* 冒泡排序实现 */ },quick: arr => { /* 快速排序实现 */ }
};
function sort(arr, type) {return strategies[type](arr);
}
console.log(sort([3,1,2], 'bubble'));
新增策略只需在 strategies 中注册即可
命令模式
- 命令模式将请求封装成对象,从而支持参数化、队列化及撤销操作
- 常用于实现可撤销操作、日志记录或事务系统。
class Command {constructor(receiver, action) {this.receiver = receiver; this.action = action;}execute() { this.receiver[this.action](); }
}
class Light { on() { console.log('Light ON'); } off() { console.log('Light OFF'); } }
const light = new Light();
const cmdOn = new Command(light, 'on');
cmdOn.execute(); // Light ON
命令可存储、排队或回滚
相关文章:
JS 高级程序设计 设计模式
设计模式是提升代码可维护性、可扩展性和可复用的重要工具 创建型模式 工厂模式 封装对象的创建过程,通过函数或类统一生成实例,避免直接使用 new 关键字简单工厂:通过函数返回不同对象实例 function createButton(type) {if (type prim…...

新电脑软件配置二:安装python,git, pycharm
安装python 地址 https://www.python.org/downloads/ 不是很懂为什么这么多版本 安装windows64位的 这里我是凭自己感觉装的了 然后cmd输入命令没有生效,先重启下? 重启之后再次验证 环境是成功的 之前是输入的python -version 命令输入错误 安装pyc…...

数据仓库:企业数据管理的核心引擎
一、数据仓库的由来 数据仓库(Data Warehouse, DW)概念的诞生源于企业对数据价值的深度挖掘需求。在1980年代,随着OLTP(联机事务处理)系统在企业中的普及,传统关系型数据库在处理海量数据分析时显露出明显瓶…...

MCU开发学习记录17* - RTC学习与实践(HAL库) - 日历、闹钟、RTC备份寄存器 -STM32CubeMX
名词解释: RTC:Real-Time Clock 统一文章结构(数字后加*): 第一部分: 阐述外设工作原理;第二部分:芯片参考手册对应外设的学习;第三部分:使用STM32CubeMX进…...

C++中的四种强制转换
static_cast 原型:static_cast<type-id>(expression) type-id表示目标类型,expression表示要转换的表达式 static_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用static_c…...

YOLOv2目标检测算法:速度与精度的平衡之道
一、YOLOv2的核心改进:从V1到V2的蜕变 YOLOv2作为YOLO系列的第二代算法,在继承V1端到端、单阶段检测的基础上,针对V1存在的小目标检测弱、定位精度低等问题进行了全方位升级,成为目标检测领域的重要里程碑。 (一&am…...
Quic如何实现udp可靠传输
QUIC(Quick UDP Internet Connections)是由 Google 设计并被 IETF 标准化的传输层协议,它基于 UDP 实现,但提供了类似 TCP 的可靠性和更高级的功能(如多路复用、0-RTT 握手、TLS 加密等)。 尽管 UDP 是不可…...

利用腾讯云MCP提升跨平台协作效率的实践与探索
一、场景痛点 在当今这个数字化快速发展的时代,跨平台协作成为了许多企业和团队面临的一个重大挑战。随着企业业务的不断拓展,团队成员往往需要利用多种工具和平台进行沟通、协作和管理。这些平台包括但不限于电子邮件、即时通讯工具、项目管理软件、文…...

【Vue篇】数据秘语:从watch源码看响应式宇宙的蝴蝶效应
目录 引言 一、watch侦听器(监视器) 1.作用: 2.语法: 3.侦听器代码准备 4. 配置项 5.总结 二、翻译案例-代码实现 1.需求 2.代码实现 三、综合案例——购物车案例 1. 需求 2. 代码 引言 💬 欢迎讨论&#…...
Python高级特性深度解析:从熟练到精通的跃迁之路
Python高级特性深度解析:从熟练到精通的跃迁之路 引言 对于已经掌握Python基础语法的开发者而言,如何突破瓶颈进入高手行列?本文将从Python的高级特性入手,深入剖析那些能让代码更优雅、效率更高的技术点,助你完成从…...

OGGMA 21c 微服务 (MySQL) 安装避坑指南
前言 这两天在写 100 天实战课程 的 OGG 微服务课程: 在 Oracle Linux 8.10 上安装 OGGMA 21c MySQL 遇到了一点问题,分享给大家一起避坑! 环境信息 环境信息: 主机版本主机名实例名MySQL 版本IP 地址数据库字符集Goldengate …...

Linux面试题集合(4)
现有压缩文件:a.tar.gz存在于etc目录,如何解压到data目录 tar -zxvf /etc/a.tar.gz -C /data 给admin.txt创建一个软链接 ln -s admin.txt adminl 查找etc目录下以vilinux开头的文件 find /etc -name vilinux* 查找admin目录下以test开头的文件 find admin -name te…...
iOS Safari调试教程
iOS Safari调试 本教程将指导您如何使用WebDebugX调试iOS设备上的Safari浏览器。通过本教程,您将学习如何连接iOS设备、调试Safari中的网页、分析性能问题以及解决常见的调试挑战。 准备工作 在开始调试iOS Safari之前,请确保您已经: 安装…...
基于互联网和LabVIEW的多通道数据采集系统仿真设计
标题:基于互联网和LabVIEW的多通道数据采集系统仿真设计 内容:1.摘要 在当今科技飞速发展的背景下,多通道数据采集在众多领域有着广泛需求。本研究的目的是设计一个基于互联网和LabVIEW的多通道数据采集系统仿真方案。采用互联网技术实现数据的远程传输与共享&…...
ffmpeg -vf subtitles添加字幕绝对路径问题的解决方法
今天遇到奇怪的问题,老是报 Unable to parse option value Error applying option original_size to filter subtitles: Invalid argument 踩坑很长时间,记录下 因subtitles需要指定绝对路径, 注意点: 外面要用单引号 不能…...

Android Studio 安装与配置完全指南
文章目录 第一部分:Android Studio 简介与安装准备1.1 Android Studio 概述1.2 系统要求Windows 系统:macOS 系统:Linux 系统: 1.3 下载 Android Studio 第二部分:安装 Android Studio2.1 Windows 系统安装步骤2.2 mac…...
级联与端到端对话系统架构解析:以Moshi为例
一、对话系统架构对比 1.1 级联对话系统(Cascaded Dialogue Systems) 传统级联系统采用多阶段处理流程: 语音识别(ASR):将24kHz音频信号通过卷积神经网络(CNN)和Transformer转换为…...

基于 Zookeeper 部署 Kafka 集群
文章目录 1、前期准备2、安装 JDK 83、搭建 Zookeeper 集群3.1、下载3.2、调整配置3.3、标记节点3.4、启动集群 4、搭建 Kafka 集群4.1、下载4.2、调整配置4.3、启动集群 1、前期准备 本次集群搭建使用:3 Zookeeper 3 Kafka,所以我在阿里云租了3台ECS用…...
经典卷积神经网络
目录 经典卷积神经网络 一、卷积神经网络基础回顾 二、LeNet:开启 CNN 先河 三、AlexNet:突破性进展 四、ZFNet:继承与优化 五、GoogLeNet:引入 Inception 模块 六、VggNet:深度与简单结构的融合 七、ResNet&a…...

IDE/IoT/搭建物联网(LiteOS)集成开发环境,基于 LiteOS Studio + GCC + JLink
文章目录 概述LiteOS Studio不推荐?安装和使用手册呢?HCIP实验的源码呢? 软件和依赖安装软件下载软件安装插件安装依赖工具-方案2依赖工具-方案1 工程配置打开或新建工程板卡配置组件配置编译器配置-gcc工具链编译器配置-Makefile脚本其他配置编译完成 …...

算法加训之最短路 上(dijkstra算法)
目录 P4779 【模板】单源最短路径(标准版)(洛谷) 思路 743. 网络延迟时间(力扣) 思路 1514.概率最大路径(力扣) 思路 1631.最小体力消耗路径 思路 1976. 到达目的地的方案数 …...
java连数据库
一、准备工作 安装MySQL数据库 确保已安装MySQL服务器并启动服务 下载JDBC驱动 官方驱动:MySQL Connector/JMaven依赖: <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactI…...

QT+Opencv 卡尺工具找直线
QTOpencv 卡尺工具找直线 自己将别的项目中,单独整理出来的。实现了一个找直线的工具类。 功能如下:1.添加图片 2.添加卡尺工具 3.鼠标可任意拖动图片和卡尺工具 4.可调整卡尺参数和直线拟合参数 5.程序中包含了接口函数,其他cpp文件传入相…...

GraphPad Prism简介、安装与工作界面
《2025GraphPad Prism操作教程书籍 GraphPad Prism图表可视化与统计数据分析视频教学版GraphPad Prism科技绘图与数据分析学术图表 GraphPadPrism图表》【摘要 书评 试读】- 京东图书 GraphPad Prism统计数据分析_夏天又到了的博客-CSDN博客 1.1 GraphPad Prism简介 GraphP…...
当AI自我纠错:一个简单的“Wait“提示如何让模型思考更深、推理更强
原论文:s1: Simple test-time scaling 作者:Niklas Muennighoff, Zitong Yang, Weijia Shi等(斯坦福大学、华盛顿大学、Allen AI研究所、Contextual AI) 论文链接:arXiv:2501.19393 代码仓库:GitHub - simp…...

esp32课设记录(一)按键的短按、长按与双击
课程用的esp32的板子上只有一个按键,引脚几乎都被我用光了,很难再外置按键。怎么控制屏幕的gui呢?这就得充分利用按键了,比如说短按、长按与双击,实现不同的功能。 咱们先从短按入手讲起。 通过查看原理图,…...
使用AI 生成PPT 最佳实践方案对比
文章大纲 一、专业AI生成工具(推荐新手)**1. 推荐工具详解****2. 操作流程优化****3. 优势与局限**二、代码生成方案(开发者推荐)**1. Python-pptx进阶用法****2. GitHub推荐**三、混合工作流(平衡效率与定制)**1. 工具链升级****2. 示例Markdown结构**四、网页转换方案(…...

React19源码系列之 API(react-dom)
API之 preconnect preconnect – React 中文文档 preconnect 函数向浏览器提供一个提示,告诉它应该打开到给定服务器的连接。如果浏览器选择这样做,则可以加快从该服务器加载资源的速度。 preconnect(href) 一、使用例子 import { preconnect } fro…...

supervisorctl守护进程
supervisorctl守护进程 1 安装 # ubuntu安装: sudo apt-get install supervisor 完成后可以在/etc/supervisor文件夹,找到supervisor.conf。 如果没有的话可以用如下命令创建配置文件(注意必须存在/etc/supervisor这个文件夹) s…...

下载的旧版的jenkins,为什么没有旧版的插件
下载的旧版的jenkins,为什么没有旧版的插件,别急 我的jenkins版本: 然后我去找对应的插件 https://updates.jenkins.io/download/plugins/ 1、Maven Integration plugin: Maven 集成管理插件。 然后点击及下载成功 然后 注意&…...