JavaScript 创建型设计模式详解

1. 单例模式

1.1. 使用场景

在前端开发中,全局状态管理、配置信息、数据库连接等往往需要在应用中只存在一个实例,避免多次实例化带来的数据不一致性。例如,在一个前端应用中,全局的 loading 状态通常需要一个单例模式来确保其唯一性。

1.2. 代码实现

class Singleton {// 构造函数为私有,防止外部直接调用constructor() {if (Singleton.instance) {return Singleton.instance;}// 初始化其他属性this.data = [];Singleton.instance = this;}// 静态方法,获取唯一的实例static getInstance() {if (!Singleton.instance) {Singleton.instance = new Singleton();}return Singleton.instance;}// 添加数据方法addData(item) {this.data.push(item);}// 获取数据方法getData() {return this.data;}
}// 使用 Singleton
const instance1 = Singleton.getInstance();
instance1.addData('First Item');const instance2 = Singleton.getInstance();
console.log(instance2.getData()); // ['First Item'], instance1 和 instance2 是同一个实例

1.3. 详细注释

  • constructor():将构造函数私有化,通过判断 Singleton.instance 是否已存在来确保单例。

  • getInstance():静态方法用于获取唯一实例,调用时如果实例不存在则创建新实例,存在则直接返回已有实例。

  • 使用 addData 和 getData 方法演示单例模式下的数据存储与获取,保证所有调用的是同一个实例。

1.4. 实际应用

  • 单例模式可用于前端中的全局配置对象、全局状态管理(如 Redux Store)、全局事件总线等。

2. 工厂方法模式

2.1. 使用场景

当我们需要创建不同类型的对象但又不想在代码中写死实例化的逻辑时,工厂方法模式能够根据条件动态生成合适的对象实例。在前端开发中,常用于根据不同配置生成相应的组件或对象。

2.2. 代码实现

class Button {constructor(type) {this.type = type;}render() {console.log(`Render a ${this.type} button`);}
}class ButtonFactory {createButton(type) {switch (type) {case 'primary':return new Button('primary');case 'secondary':return new Button('secondary');default:throw new Error('Button type not supported');}}
}// 使用工厂方法
const factory = new ButtonFactory();
const primaryButton = factory.createButton('primary');
primaryButton.render(); // Render a primary button

2.3. 详细注释

  • Button:表示一个具体的按钮对象,通过 type 来区分不同类型的按钮。

  • ButtonFactory:工厂类用于创建不同类型的按钮对象,提供了 createButton 方法,根据传入的 type 动态生成对应的实例。

  • 通过工厂方法来解耦实例化逻辑和对象使用,便于扩展。

2.4. 实际应用

  • 工厂方法模式常用于创建复杂的对象实例,例如组件库中的动态组件生成、API 服务实例化等。

3. 抽象工厂模式

3.1. 使用场景

当需要创建一组相关或相互依赖的对象时,抽象工厂模式能帮助我们统一创建流程。在前端框架中,常用于根据环境或用户设置来创建不同的一组 UI 组件或工具。

3.2. 代码实现

class MacButton {render() {console.log('Render a Mac button');}
}class WindowsButton {render() {console.log('Render a Windows button');}
}class MacFactory {createButton() {return new MacButton();}
}class WindowsFactory {createButton() {return new WindowsButton();}
}function createUI(factory) {const button = factory.createButton();button.render();
}// 使用抽象工厂
const macFactory = new MacFactory();
createUI(macFactory); // Render a Mac buttonconst windowsFactory = new WindowsFactory();
createUI(windowsFactory); // Render a Windows button

3.3. 详细注释

  • MacButton 与 WindowsButton:表示不同平台下的按钮组件。

  • MacFactory 与 WindowsFactory:各自负责创建相应平台的组件,通过 createButton 方法创建相应的按钮对象。

  • 通过抽象工厂模式,确保了创建一整套相关联对象的流程简单统一。

3.4. 实际应用

  • 抽象工厂模式广泛用于创建跨平台 UI 组件、表单控件等场景。

4. 建造者模式

4.1. 使用场景

当一个对象的创建需要依赖多个步骤或者多个部分时,建造者模式能通过逐步构建的方式来确保创建流程的清晰和可控。适合在前端复杂组件的创建中使用,例如动态表单、复杂配置对象等。

4.2. 代码实现

class Form {constructor() {this.fields = [];}addField(field) {this.fields.push(field);}getForm() {return this.fields;}
}class FormBuilder {constructor() {this.form = new Form();}addTextField(label) {this.form.addField({ type: 'text', label });return this;}addCheckboxField(label) {this.form.addField({ type: 'checkbox', label });return this;}build() {return this.form;}
}// 使用建造者模式
const formBuilder = new FormBuilder();
const form = formBuilder.addTextField('Name').addCheckboxField('Subscribe').build();console.log(form.getForm()); // [{type: 'text', label: 'Name'}, {type: 'checkbox', label: 'Subscribe'}]

4.3. 详细注释

  • Form:表示表单对象,包含表单字段的数组。

  • FormBuilder:提供了一系列方法,用于动态添加表单字段,通过 build 方法返回构建好的表单。

  • 通过建造者模式,可以灵活地构建复杂对象,同时保持代码的简洁和可读性。

4.4. 实际应用

  • 建造者模式常用于创建多步骤配置的对象,如复杂的 UI 组件、表单生成器、配置对象等。

5. 原型模式

5.1. 使用场景

当我们需要快速创建对象的副本时,原型模式可以通过拷贝已有对象来避免重复的初始化操作。常用于需要大量类似对象的场景,如渲染大量类似的 UI 组件或节点。

5.2. 代码实现

class Prototype {constructor(data) {this.data = data;}clone() {return new Prototype(this.data);}
}// 使用原型模式
const original = new Prototype({ name: 'Original' });
const clone = original.clone();console.log(original.data); // { name: 'Original' }
console.log(clone.data); // { name: 'Original' }
console.log(original === clone); // false

5.3. 详细注释

  • Prototype:表示原型对象,提供了 clone 方法用于创建对象的副本。

  • clone():返回一个新对象,拷贝了原对象的数据,实现了对象的快速复制。

  • 原型模式避免了重新创建和初始化对象的复杂性。

5.4. 实际应用

  • 原型模式常用于需要大量创建相似对象的场景,如游戏开发中的对象克隆、前端应用中的组件渲染等。

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

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

相关文章

k8s除了主server服务器可正常使用kubectl命令,其他节点不能使用原因,以及如何在其他k8s节点正常使用kubectl命令??

kubectl 并不是“只能”在主节点(Control Plane Node)使用,而是因为它需要访问 Kubernetes 的 kube-apiserver,而 kube-apiserver 通常只在主节点上运行并监听内部网络。简单来说kubectl 需要连接 kube-apiserver!&…

Custom SRP - Complex Maps

https://catlikecoding.com/unity/tutorials/custom-srp/complex-maps/1 创建材质球我们的材质已经支持光照,并且支持 Albedo 和 Emission 贴图.创建材质球,并应用下面的电路板的图分别作为 albedo emission设置材质球的金属度为 1 , 光滑度为 0.952 Mask Map在 albedo 图上的不…

repo 学习教程

你现在会用 git 了,接下来学 repo(Google 推出来的多仓库管理工具),其实就是在 Git 的基础上做了一层封装,方便同时管理很多 Git 仓库。像 Android 源码、Rockchip 全套 SDK 都是靠 repo 来拉取和管理的。 我给你分几个…

[SWERC 2020] Safe Distance题解

[SWERC 2020] Safe Distance 题意 给定 NNN 个点与一个坐标 (X,Y)(X,Y)(X,Y),求从点 (0,0)(0,0)(0,0) 到点 (X,Y)(X,Y)(X,Y) 规划一条路线,不能走出 (0,0)(0,0)(0,0) 与 (X,Y)(X,Y)(X,Y) 间形成的矩形,使得通过这条路线时距离最近的点的距离…

Rewind-你人生的搜索引擎

本文转载自:Rewind-你人生的搜索引擎 - Hello123工具导航 ** 一、🔍 Rewind 是什么?你的数字记忆增强神器 Rewind 是一款人工智能驱动的个人记忆助手,就像为你配备了一个「数字第二大脑」。它能自动记录、保存并索引你在电脑和手…

开发小点 - 存

开发小点 1.Req注解 EqualsAndHashCode(callSuper true) Data public class BillSituationReq extends BillQueryReq {/*** Whether to display the ring ratio, default is not displayed*/ApiModelProperty("Whether to Display YoY Comparison")private Boolean …

只会npm install?这5个隐藏技巧让你效率翻倍!

原文链接:https://mp.weixin.qq.com/s/nijxVWj-E5U08DX2fl3vgg最近有个刚学前端的小伙伴问我:“为什么我的node_modules这么大?为什么别人装依赖那么快?npx到底是啥玩意儿?” 相信不少人都跟他一样,对npm的…

(二).net面试(static)

文章目录项目地址一、基础501.1 new keyword1.2 static class vs. static method1. static class2. static method3. static constructor 静态构造函数4. 静态成员的生命周期1.3 LinQ1.what is LinQ2. List<T>、IEnumerable<T>、IQueryable<T>3. 在数据库里用…

docker,本地目录挂载

理解Docker本地目录挂载的基本概念Docker本地目录挂载允许容器与宿主机共享文件或目录&#xff0c;实现数据持久化和实时交互。挂载方式分为bind mount和volume两种&#xff0c;前者直接映射宿主机路径&#xff0c;后者由Docker管理存储路径。本地目录挂载的核心方法bind mount…

IO多路复用相关知识

select、poll、epoll 在传入的性能差异是不是体现在&#xff0c;当有新的连接过来&#xff0c;此时需要将新的fd传入到内核中&#xff0c;但是poll/select需要出入整个数组&#xff0c;而epoll方式只需要出入单个fd&#xff1f; 1. select/poll 的情况它们没有内核中“长期保存…

【CF】Day139——杂题 (绝对值变换 | 异或 + 二分 | 随机数据 + 图论)

B. Meeting on the Line题目&#xff1a;思路&#xff1a;数形结合首先考虑如果没有 t 的影响该怎么写显然我们就是让最大时间最小化&#xff0c;那么显然选择最左端点和最右端点的中间值即可&#xff0c;即 (mi mx) / 2&#xff0c;那么现在有了 t 该怎么办我们不妨考虑拆开绝…

在 Ubuntu 上安装和配置 PostgreSQL 实录

一、查看ubuntu版本 lsb_release -a postgresq尽量安装在新的稳定版本的ubuntu上 二、安装postgresql 2.1 直接安装 sudo apt install postgresql 结果如下 2.2 使用PPA源安装 Ubuntu官方源提供了PostgreSQL的PPA(Personal Package Archive),通过PPA源安装可以确保获取…

WebGIS三维可视化 + 数据驱动:智慧煤仓监控系统如何破解煤炭仓储行业痛点

目录 一、项目背景&#xff1a;煤炭仓储管理的痛点与转型需求 二、建设意义&#xff1a;从 “被动管理” 到 “主动掌控” 的价值跃迁 三、项目核心&#xff1a;技术架构与核心目标的深度融合 四、数据与技术&#xff1a;系统稳定运行的 “双支柱” &#xff08;一&#x…

使用 Spring Security 实现 OAuth2:一步一步的操作指南

前言 OAuth 是一种授权框架&#xff0c;用于创建权限策略&#xff0c;并允许应用程序对用户在 HTTP 服务&#xff08;如 GitHub 和 Google&#xff09;上的账户进行有限访问。它的工作原理是允许用户授权第三方应用访问他们的数据&#xff0c;而无需分享他们的凭证。本文将指导…

VMware共享文件夹设置

启用共享文件夹 编辑虚拟机设置-选项-共享文件夹&#xff0c;上面的选项选择启用下面点击添加一个路径&#xff0c;跟着向导走 设置共享文件夹在主机的路径&#xff0c;和文件夹名称添加完成后可以点击这个共享文件夹条目&#xff0c;查看属性虚拟机里安装vm-tools sudo apt up…

华为云昇腾云服务

华为云&#xff0c;一切皆服务共建智能世界云底座面向未来的智能世界&#xff0c;数字化是企业发展的必由之路。数字化成功的关键是以云原生的思维践行云原生&#xff0c;全数字化、全云化、AI驱动&#xff0c;一切皆服务。华为云将持续创新&#xff0c;携手客户、合作伙伴和开…

Axum 最佳实践:如何构建优雅的 Rust 错误处理系统?(三)

引言 作为开发者&#xff0c;我们都经历过这样的场景&#xff1a;项目上线后&#xff0c;你打开日志监控&#xff0c;铺天盖地的 500 Internal Server Error 扑面而来。这些错误像个黑洞&#xff0c;吞噬着你的调试时间&#xff0c;你甚至不知道它们是从数据库查询失败&#x…

MySQL高可用方案解析:从复制到云原生

MySQL 的高可用 (High Availability, HA) 方案旨在确保数据库服务在硬件故障、软件崩溃、网络中断或计划维护时仍能持续可用&#xff0c;最小化停机时间&#xff08;通常目标为 99.9% 至 99.999% 可用性&#xff09;。以下是 MySQL 领域成熟且广泛应用的几种主流高可用方案&…

腾讯云语音接口实现会议系统

1.前言 在现代企业协作环境中&#xff0c;高效的会议管理是提升团队生产力的关键。本文将深入解析一个完整的会议管理系统&#xff0c;涵盖从会议创建到总结生成的完整生命周期。该系统构建一个基于AI技术的智能会议系统&#xff0c;实现会议全流程的智能化管理&#xff0c;包括…

【LeetCode 每日一题】1277. 统计全为 1 的正方形子矩阵

Problem: 1277. 统计全为 1 的正方形子矩阵 文章目录整体思路完整代码时空复杂度时间复杂度&#xff1a;O(m * n)空间复杂度&#xff1a;O(m * n)整体思路 这段代码旨在解决一个经典的二维矩阵问题&#xff1a;统计全为 1 的正方形子矩阵个数 (Count Square Submatrices with …