【前端设计模式】之工厂模式
工厂模式特性
工厂模式是一种创建对象的设计模式,它通过使用工厂类来封装对象的创建逻辑,隐藏了具体对象的实例化过程。工厂模式的主要特性包括:
- 封装对象的创建过程:工厂模式将对象的创建过程封装在一个工厂类中,客户端只需要通过调用工厂类的方法来获取所需的对象,而无需关心具体的实例化过程。
- 提供统一的接口:工厂模式通常会定义一个统一的接口或基类,所有由工厂创建的对象都实现该接口或继承该基类,使得客户端可以统一对待不同类型的对象。
- 可扩展性:通过添加新的具体产品类和对应的具体工厂类,可以方便地扩展系统中可以创建的对象类型。
前端应用示例
在前端开发中,常见使用工厂模式来创建不同类型的组件、插件或者服务。以下是一个简单示例:
// 定义产品接口
class Product {constructor(name) {this.name = name;}getName() {return this.name;}
}// 定义具体产品类
class ConcreteProductA extends Product {constructor() {super('Product A');}
}class ConcreteProductB extends Product {constructor() {super('Product B');}
}// 定义工厂类
class Factory {createProduct(type) {switch (type) {case 'A':return new ConcreteProductA();case 'B':return new ConcreteProductB();default:throw new Error('Invalid product type.');}}
}// 使用示例
const factory = new Factory();
const productA = factory.createProduct('A');
console.log(productA.getName()); // Output: "Product A"const productB = factory.createProduct('B');
console.log(productB.getName()); // Output: "Product B"
在上面的示例中,我们首先定义了一个产品接口Product
,并实现了两个具体产品类ConcreteProductA
和ConcreteProductB
。然后,我们定义了一个工厂类Factory
,其中的createProduct
方法根据传入的参数类型来创建对应的产品对象。
1. UI组件库
在前端开发中,我们经常会使用UI组件库来构建用户界面。工厂模式可以用来创建不同类型的UI组件,例如按钮、表单、对话框等。通过使用工厂模式,我们可以将具体的组件创建逻辑封装在工厂类中,使得客户端代码与具体组件类解耦。
// 定义按钮组件接口
class Button {render() {// 渲染按钮}
}// 定义具体按钮组件类
class PrimaryButton extends Button {render() {// 渲染主要按钮样式}
}class SecondaryButton extends Button {render() {// 渲染次要按钮样式}
}// 定义按钮工厂类
class ButtonFactory {createButton(type) {switch (type) {case 'primary':return new PrimaryButton();case 'secondary':return new SecondaryButton();default:throw new Error('Invalid button type.');}}
}// 使用示例
const buttonFactory = new ButtonFactory();
const primaryButton = buttonFactory.createButton('primary');
primaryButton.render(); // 渲染主要按钮样式const secondaryButton = buttonFactory.createButton('secondary');
secondaryButton.render(); // 渲染次要按钮样式
2. 数据请求库
工厂模式可以用来创建不同类型的数据请求对象,例如基于XMLHttpRequest的Ajax请求、基于Fetch API的请求等。通过使用工厂模式,我们可以根据不同的需求选择合适的数据请求对象,并统一对待不同类型的请求。
// 定义数据请求接口
class DataRequest {send(url, options) {// 发送数据请求并返回结果}
}// 定义具体数据请求类(基于XMLHttpRequest)
class XHRRequest extends DataRequest {send(url, options) {// 使用XMLHttpRequest发送请求并返回结果}
}// 定义具体数据请求类(基于Fetch API)
class FetchRequest extends DataRequest {send(url, options) {// 使用Fetch API发送请求并返回结果}
}// 定义数据请求工厂类
class DataRequestFactory {createRequest(type) {switch (type) {case 'xhr':return new XHRRequest();case 'fetch':return new FetchRequest();default:throw new Error('Invalid request type.');}}
}// 使用示例
const requestFactory = new DataRequestFactory();
const xhrRequest = requestFactory.createRequest('xhr');
xhrRequest.send(' https://api.example.com/data ', { method: 'GET' });const fetchRequest = requestFactory.createRequest('fetch');
fetchRequest.send(' https://api.example.com/data ', { method: 'GET' });
3. 插件系统
工厂模式可以用来创建插件对象,并提供统一的接口供客户端使用。通过使用工厂模式,我们可以方便地添加新的插件,并统一管理和调用插件。
// 定义插件接口
class Plugin {init() {// 初始化插件}
}// 定义具体插件类
class AnalyticsPlugin extends Plugin {init() {// 初始化统计插件}
}class LoggerPlugin extends Plugin {init() {// 初始化日志插件}
}// 定义插件工厂类
class PluginFactory {createPlugin(type) {switch (type) {case 'analytics':return new AnalyticsPlugin();case 'logger':return new LoggerPlugin();default:throw new Error('Invalid plugin type.');}}
}// 使用示例
const pluginFactory = new PluginFactory();
const analyticsPlugin = pluginFactory.createPlugin('analytics');
analyticsPlugin.init(); // 初始化统计插件const loggerPlugin = pluginFactory.createPlugin('logger');
loggerPlugin.init(); // 初始化日志插件
4. 路由管理器
在单页应用(SPA)开发中,路由管理器负责根据URL路径加载对应的页面或组件。工厂模式可以用来创建路由对象,并根据不同的URL路径返回对应的页面或组件。通过使用工厂模式,我们可以方便地扩展路由规则,并统一管理路由逻辑。
// 定义路由接口
class Router {navigate(url) {// 根据URL导航到对应的页面或组件}
}// 定义具体路由类
class HashRouter extends Router {navigate(url) {// 使用哈希路由导航到对应的页面或组件}
}class HistoryRouter extends Router {navigate(url) {// 使用历史路由导航到对应的页面或组件}
}// 定义路由工厂类
class RouterFactory {createRouter(type) {switch (type) {case 'hash':return new HashRouter();case 'history':return new HistoryRouter();default:throw new Error('Invalid router type.');}}
}// 使用示例
const routerFactory = new RouterFactory();
const hashRouter = routerFactory.createRouter('hash');
hashRouter.navigate('/home'); // 根据哈希路由导航到首页const historyRouter = routerFactory.createRouter('history');
historyRouter.navigate('/about'); // 根据历史路由导航到关于页面
这些示例展示了工厂模式在不同场景下的应用,通过使用工厂模式,我们可以封装对象的创建逻辑,提高代码的可维护性和可扩展性。同时,工厂模式还可以提供统一的接口或基类,使得客户端可以统一对待不同类型的对象。
优缺点
优点
- 将对象的创建逻辑封装在工厂类中,使得客户端代码与具体产品类解耦,提高了代码的可维护性和可扩展性。
- 可以通过添加新的具体产品类和对应的具体工厂类来扩展系统中可以创建的对象类型。
- 提供统一的接口或基类,使得客户端可以统一对待不同类型的对象。
缺点
- 增加了系统中的类数量,增加了代码复杂度。
- 对于简单对象创建逻辑而言,引入工厂模式可能会增加不必要的复杂性。
总结
工厂模式是一种常用的创建对象的设计模式,它通过封装对象的创建逻辑,提供统一的接口,实现了代码的解耦和可扩展性。在实际开发中,可以根据具体需求选择是否使用工厂模式来创建对象。工厂模式可以应用于任何需要创建对象的场景。通过使用工厂模式,我们可以提高代码的可维护性、可扩展性和可测试性,使得代码更加灵活和易于理解。
相关文章:
【前端设计模式】之工厂模式
工厂模式特性 工厂模式是一种创建对象的设计模式,它通过使用工厂类来封装对象的创建逻辑,隐藏了具体对象的实例化过程。工厂模式的主要特性包括: 封装对象的创建过程:工厂模式将对象的创建过程封装在一个工厂类中,客…...

Hive 的函数介绍
目录 编辑 一、内置运算符 1.1 关系运算符 1.2算术运算符 1.3逻辑运算符 1.4复杂类型函数 1.5对复杂类型函数操作 二、内置函数 2.1数学函数 2.2收集函数 2.3类型转换函数 2.4日期函数 2.5条件函数 2.6字符函数 三、内置的聚合函数 四、内置表生成函数 五、…...

【Linux基础】第31讲 Linux用户和用户组权限控制命令(三)
用户组管理命令 每个用户都有一个用户组,系统可以对一个用户组中的所有用户进行集中管理。不同Linux系统对用户组的规定有所不同。如Linux下的用户属于与它同名的用户组,这个用户组在创建用户时同时创建。用户组的管理涉及用户组的添加、删除和修改。组…...

html form表单高级用法
场景:想单纯使用表单内置的api完成提交,不使用js代码 代码如下: <form name"myForm" action"http://localhost:13734/form" method"post"><label>用户名<input type"text" name&qu…...
openssl升级
参考 https://www.cnblogs.com/shareHistory/p/15850707.html 下载并安装依赖 wget https://www.openssl.org/source/openssl-3.0.5.tar.gz yum -y install perl-IPC-Cmd编译安装 ./config -Wl,-rpath/usr/local/openssl/lib -fPIC --prefix/usr/local/openssl --openssldir…...

【数据结构】图的遍历:广度优先(BFS),深度优先(DFS)
目录 1、广度优先(BFS) 算法思想 广度优先生成树 知识树 代码实现 2、深度优先(DFS) 算法思想 深度优先生成树 知识树 代码实现 1、广度优先(BFS) 算法思想 图的广度优先遍历࿰…...
Mysql 学习总结(89)—— Mysql 库表容量统计
前言 统计每个库每个表的大小是数据治理中最简单的一个要求,下面从抽样统计结果及精确统计结果两方面来统计MySQL的每个库每个表的数据量情况。mysql 数据字典库 information_schema 里记录了统计的预估数据量(innodb 引擎表不准确,MyISAM 引擎表准确)及数据大小、索引大小及…...

virtualBox安装配置使用
virtualBox下载 //官网下载地址 https://www.virtualbox.org/wiki/Downloads //ubuntu下载地址 https://cn.ubuntu.com/download/server/step1 virtualBox使用 导入现有镜像 (如果报错可以降低系统配置,因为有些主机可能不支持高配置,例如…...

北斗导航 | RTD、RTK完好性之B值、VPL与HPL计算(附B值计算matlab源代码)
===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 1、S矩阵获取 为第i颗卫星测距标准差:...
more often than not 的含义
今天听https://www.bilibili.com/video/BV1w94y12727/?p2&spm_id_frompageDriver more often than not 连读:mor ofen than au 想了半天不动什么意思. 查了一下表示大部分情况下. 还是不理解为什么, 就查了必应里面的词典. 表示超过一半的情况下. 又自己想了想突然懂了.…...

【Linux】Linux环境配置安装
目录 一、双系统(特别不推荐) 安装双系统的缺点: 安装双系统优点(仅限老手): 二、虚拟机centos7镜像(较为推荐推荐) 虚拟机的优点: 虚拟机的缺点: …...

从零学习开发一个RISC-V操作系统(二)丨GCC编译器和ELF格式
本篇文章的内容 一、GCC(GUN Compiler Collection)1.1 GCC的命令格式1.2 GCC的主要执行步骤1.3 GCC涉及的文件类型 二、ELF简介2.1 ELF文件格式图2.2 ELF文件处理的相关工具2.3 练习 本系列是博主参考B站课程学习开发一个RISC-V的操作系统的学习笔记&…...

论文阅读_大语言模型_Llama2
英文名称: Llama 2: Open Foundation and Fine-Tuned Chat Models 中文名称: Llama 2:开源的基础模型和微调的聊天模型 文章: http://arxiv.org/abs/2307.09288 代码: https://github.com/facebookresearch/llama 作者: Hugo Touvron 日期: 2023-07-19 引用次数: 11…...

当量因子法、InVEST、SolVES模型等多技术融合在生态系统服务功能社会价值评估中的应用及论文写作、拓展分析
生态系统服务是人类从自然界中获得的直接或间接惠益,可分为供给服务、文化服务、调节服务和支持服务4类,对提升人类福祉具有重大意义,且被视为连接社会与生态系统的桥梁。自从启动千年生态系统评估项目(Millennium Ecosystem Asse…...
k8s Limits 限制内存
Limits 限制内存 在 Kubernetes (K8s) 中,可以使用 Limits(资源限制)来限制 Pod(容器)使用的内存数量。此处的 Limits 表示 Pod 在 K8s 集群中可用的最大内存量。一旦 Pod 内存使用超过这个限制,可能会触发…...

单片机第三季-第三课:STM32开发板原理图、配置、浮点运算单元
目录 1,开发板原理图 2,浮点运算单元(FPU) 1,开发板原理图 课程视频比较早,介绍了三款开发板。观看视频时用的开发板说和51单片机共板的STM32核心板,将51单片机从底座拆下来后,安…...
观察者模式 发布-订阅模式(设计模式与开发实践 P8)
文章目录 观察者模式运用实现 观察者模式 定义:他用来定义对象之间一种一对多的依赖关系,当一个对象状态发生改变时,所有依赖他的对象都会得到通知 运用 如果我们使用过 DOM 上的事件函数,那就接触过观察者模式 document.body…...

【日常业务开发】Java实现异步编程
【日常业务开发】Java实现异步编程 Java实现异步编程什么是异步异步的八种实现方式异步编程线程异步Future异步CompletableFuture实现异步Spring的Async异步Spring ApplicationEvent事件实现异步消息队列ThreadUtil异步工具类Guava异步 CompletableFuture异步编排工具类创建异步…...

学习笔记|模数转换器|ADC原理|STC32G单片机视频开发教程(冲哥)|第十七集:ADC采集
文章目录 1.模数转换器(ADC)是什么?手册说明: 2.STC32G单片机ADC使用原理19.1.1 ADC控制寄存器(ADC_CONTR)19.1.2 ADC配置寄存器(ADCCFG)19.1.4ADC时序控制寄存器(ADCTIM)19.3 ADC相…...

OpenCV实现“蓝线挑战“特效
原理 算法原理可以分为三个流程: 1、将视频(图像)从(顶->底)或(左->右)逐行(列)扫描图像。 2、将扫描完成的行(列)像素重新生成定格图像…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...