JavaScript设计模式(二)——简单工厂模式、抽象工厂模式、建造者模式
个人简介
👀个人主页: 前端杂货铺
🙋♂️学习方向: 主攻前端方向,正逐渐往全干发展
📃个人状态: 研发工程师,现效力于中国工业软件事业
🚀人生格言: 积跬步至千里,积小流成江海
🥇推荐学习:🍍前端面试宝典 🍉Vue2 🍋Vue3 🍓Vue2/3项目实战 🥝Node.js🍒Three.js 🍖JS版算法
🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧
文章目录
- ✨✨前言
- 一、简单工厂模式
- 二、抽象工厂模式
- 三、建造者模式
- 🎉🎉本篇小结
✨✨前言
大家好,这里是前端杂货铺。
上一节,我们学习了构造器模式、原型模式和类模式,并认识到了类模式 = 构造器模式 + 原型模式。这一节,我们学习简单工厂模式、抽象工厂模式和建造者模式,认识它们的用途以及区别…
一、简单工厂模式
由一个简答工厂对象决定创建某一种产品对象类的实例。主要用来创建某一类对象。
举个栗子:对于后台管理系统,一般都会有 侧边栏权限分配 的问题。比如说:
- superadmin 的权限包括 “home”, “user-manager”, “right-manage”, “news-manage”。
- admin 的权限包括 “home”, “user-manage”, “news-manage”
- editor 的权限包括 “home”, “news-manage”
那么当某类人员登录进来,侧边栏就需要显示该人员权限范围内的功能,这时候就可以使用简单工厂模式。
class User {constructor(role, pages) {this.role = role;this.pages = pages;}static UserFactory(role) {switch (role) {case "superadmin":console.log(new User("superadmin", ["home", "user-manager", "right-manage", "news-manage"]));break;case "admin":console.log(new User("admin", ["home", "user-manage", "news-manage"]));break;case "editor":console.log(new User("editor", ["home", "news-manage"]));break;default:throw new Error("参数错误");}}
}let user = User.UserFactory("superadmin");
console.log(user);

简单工厂模式的优点:我们只需要一个正确的参数,就可以获取到我们所需要的对象,无需知道其创建的具体细节。
简单工厂模式的缺点:当我们的对象较多时,函数会非常庞大,难以维护。
so,简单工厂模式只适用于 创建的对象数量较少,对象的创建逻辑不复杂时使用。
二、抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是 围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
抽象工厂模式并不直接生成实例,而是用于对产品类簇的创建。
我们先创建一个 User 类(超级工厂),里面有两个方法,welcome() 方法用于欢迎某一类人,dataShow() 方法用于打印某一类人(子类重写的方式)。
之后我们创建三个子类 SuperAdmin、Admin、Editor(其他工厂),均继承自 User,它们继承父类的 name 和 welcome() 方法,重写父类的 dataShow() 方法。
最后我们创建 getAbstractUserFactory() 函数,传 role 参数,通过 switch - case 返回相应的类进行权限分配。
这样我们就对原本庞大的函数进行了解耦,更加容易理解和维护。
class User {constructor(name, role, pages) {this.name = name;this.role = role;this.pages = pages;}welcome() {console.log("欢迎回来", this.name);}dataShow() {throw new Error("抽象方法需要被实现");}
}class SuperAdmin extends User {constructor(name) {super(name, "superadmin", ["home", "user-manager", "right-manage", "news-manage"]);}dataShow() {console.log("superadmin-datashow");}
}class Admin extends User {constructor(name) {super(name, "admin", ["home", "user-manage", "news-manage"]);}dataShow() {console.log("admin-datashow");}
}class Editor extends User {constructor(name) {super(name, "editor", ["home", "news-manage"]);}dataShow() {console.log("editor-datashow");}
}function getAbstractUserFactory(role) {switch(role) {case "superadmin": return SuperAdmin;case "admin":return Admin;case "editor":return Editor;default: throw new Error("参数错误");}
}let UserClass = getAbstractUserFactory("admin");
let user = new UserClass("前端杂货铺");
user.dataShow();
user.welcome();

三、建造者模式
建造者模式属于创建型模式的一种,提供一种创建复杂对象的方式。它将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式是 一步一步的 创建一个复杂的对象,它 允许用户只通过指定复杂的对象的类型和内容就可以构建它们,用户不需要指定内部的具体构造细节。
我们模拟一下场景。如下图,我们把 分类菜单 看做 NavBar,把 热门推荐列表的内容 看做 List。当页面加载的时候,会首先初始化(即 init) NavBar 和 List,之后异步获取相应数据(即 getData),最后进行页面渲染(即 render)。

我们构建了两个同性质的类 Navbar 和 List(干的事是一样的,都是 init => getData => render),之后创建了建造者类 Creator,并添加了一个异步的 startBuild 方法,它接收一个参数 builder (即 Navbar 或 List 类的实例)。我们创建一个 Creator 的实例,通过实例去调用之后 startBuild 方法,之后就可以把复杂的对象一步步创建出来了。
class Navbar {init() {console.log("navbar-init");}getData() {console.log("navbar-getData");return new Promise((resolve) => {setTimeout(() => {resolve('navbar-zahuopu');}, 1000);})}render() {console.log("navbar-render");}
}class List {init() {console.log("list-init");}getData() {console.log("list-getData");return new Promise((resolve) => {setTimeout(() => {resolve('list-zahuopu');}, 1000);})}render() {console.log("list-render");}
}class Creator {async startBuild(builder) {await builder.init();await builder.getData();await builder.render();}
}const op = new Creator();
op.startBuild(new Navbar());
op.startBuild(new List());

🎉🎉本篇小结
简单工厂模式和抽象工厂模式都隶属于设计模式中的 创建型模式。
简单工厂模式是 由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
抽象工厂模式是指 当有多个抽象角色时使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象。
建造者模式 将一个复杂对象的构建层与其表示层相互分离,同样的构建过程可采用不同的表示。工厂模式主要是为了创建对象实例或者类簇(抽象工厂),关心的最终产出的是什么,而不关心创建的过程。而建造者模式关心的是创建这个对象的整个过程,甚至于创建对象的每一个细节。
好啦,本篇文章到这里就要和大家说再见啦,祝你这篇文章阅读愉快,你下篇文章的阅读愉快留着我下篇文章再祝!
参考资料:
- 菜鸟教程 · 抽象工厂模式
- 百度百科 · 简单工厂模式,抽象工厂模式
- JavaScript设计模式 【作者:千锋教育】

相关文章:
JavaScript设计模式(二)——简单工厂模式、抽象工厂模式、建造者模式
个人简介 👀个人主页: 前端杂货铺 🙋♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…...
DEAP库文档教程五----计算统计
本小结将重点围绕模型在计算统计方面的问题,进行详细的论述 1、Computing Statistics 通常情况下,我们想要在优化过程中编辑数据。Statistic模块可以在任何设计好的目标上改变一些本不可改变的数据。为了达到这个目的,需要使用与工具箱中完…...
新型安卓恶意软件使用Protobuf协议窃取用户数据
近日有研究人员发现,MMRat新型安卓银行恶意软件利用protobuf 数据序列化这种罕见的通信方法入侵设备窃取数据。 趋势科技最早是在2023年6月底首次发现了MMRat,它主要针对东南亚用户,在VirusTotal等反病毒扫描服务中一直未被发现。 虽然研究…...
【AI数字人】如何基于DINet+Openface自训练AI数字人
文章目录 OpenFace环境配置提取特征特征处理DINet推理数据前处理训练frame training stageclip training stage参考DINet训练/推理过程中需要用到OPenFace的人脸数据,所以使用DINet训练定制数字人,需要配置OPenFace和DINet两个项目的环境。我是使用conda创建了一个dinet的虚拟…...
Stable Diffusion 多视图实践
此教程是基于秋叶的webui启动器 1.Stable Diffsuion 使用多视图需要准备一个多角度open pose 图 我给大家提供一个可使用的。 2.需要添加图片到到controlnet当中,不要选择预处理器,选择模型为openpose的模型,然后需要点选同步图片尺寸。 3.然后填写关键字可以参照一下这个…...
【实操干货】如何开始用Qt Widgets编程?(四)
Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。 在本文中࿰…...
解决window安装docker报错问题
第一次打开Docker Desktop后提示错误 试了网上版本都没用,后面发现是电脑没有下载相关虚拟机: 先点击链接下载wsl2,下载后命令行执行:dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /…...
茄子科技面试题
1、RPC的重要组成有哪些? 客户端(Client):发起RPC请求的部分。客户端包含代表远程过程的存根(stub),它提供与本地过程相同的接口。 服务器(Server):接受RPC请…...
postgis数据库导出csv表再导入postgis
1、导出csv表 from settings_Address import * from sqlalchemy import create_engine, MetaData import pandas as pd def create_conn(Postgis_user,Postgis_password,Postgis_host,Postgis_port,dbname_PG):# return create_engine(PostgispyPostgis://{}:{}{}:{}/{}.forma…...
MySQL 特殊字符
文章目录 1.注释符2.字符串符3.反引号4.模式匹配通配符转义符 参考文献 1.注释符 SQL 注释是用来在 SQL 语句中添加对代码的解释说明。SQL 支持两种类型的注释符号。 单行注释:使用两个连续的减号(–)表示。减号后面的内容将被视为注释&…...
Chrome自动升级了,找不到最新版本的webdriver怎么办?
Chrome自动升级了,找不到最新版本的webdriver怎么办? 背景解决办法 背景 我用Selenium开发了Facebook和Linkedin爬虫,有些新需求要调一下,今天启动selenium时有报错,报错如下:selenium.common.exceptions.SessionNotCreatedExce…...
网络编程套接字(3): 简单的TCP网络程序
文章目录 网络编程套接字(3)4. 简单的TCP网络程序4.1 服务端创建(1) 创建套接字(2) 绑定端口(3) 监听(4) 获取新连接(5) 处理读取与写入 4.2 客户端创建(1)连接服务器 4.3 代码编写(1) v1__简单发送消息(2) v2_多进程版本(3) v3_多线程版本(4) v4_线程池版本 网络编程套接字(3)…...
springMVC之拦截器
文章目录 前言一、拦截器的配置二、拦截器的三个抽象方法三、多个拦截器的执行顺序总结 前言 拦截器 一、拦截器的配置 SpringMVC中的拦截器用于拦截控制器方法的执行 SpringMVC中的拦截器需要实现HandlerInterceptor SpringMVC的拦截器必须在SpringMVC的配置文件中进行配置&…...
docker搭建个人网盘和私有仓库Harbor
目录 1、使用mysql:5.7和 owncloud 镜像,构建一个个人网盘 2、安装搭建私有仓库 Harbor 1、使用mysql:5.7和owncloud,构建一个个人网盘 1.拉取mysql:5.6镜像,并且运行mysql容器 [rootnode8 ~]# docker pull mysql:5.7 [rootnode8 ~]# doc…...
智慧排水监测系统,科技助力城市排水治理
城市里,人们每天通过道路通行,人多,路窄,都会拥堵。同样,下雨天,雨水通过雨篦汇集、管道输送,最终排出去,当雨水过大,或者管道过窄,或者管道不通畅࿰…...
部署java程序的服务器cpu过高如何排查和解决
1.top命令找到占用CPU高的Java进程PID 2.根据进程ID找到占用CPU高的线程 ps -mp pid -o THREAD,tid | sort -r ps -mp 124682 -o THREAD,tid | sort -r 3.将指定的线程ID输出为16进制格式 printf “%x\n” tid printf "%x\n" 6384 18f0 4.jstack pid |…...
合宙Air724UG LuatOS-Air LVGL API控件--按钮 (Button)
按钮 (Button) 按钮控件,这个就不用多说了,界面的基础控件之一。 示例代码 – 按键回调函数 event_handler function(obj, event) if event lvgl.EVENT_CLICKED then print(“Clicked\n”) elseif event lvgl.EVENT_VALUE_CHANGED then print(“To…...
new/delete与malloc/free的区别
new/delete与malloc/free的区别 new、delete是C中的操作符,而malloc、free是标准库函数。 new 和 delete 是类型安全的,它们能够根据要分配的对象类型进行内存分配和释放,并调用相应的构造函数和析构函数。而 malloc 和 free 则是无类型的&am…...
QT listWidget 中实现元素的自由拖拽
QListWIdget中拖拽元素移动 setMovement(QListView::Movement::Free);setDragEnabled(true); setDragDropMode(DragDropMode::DragDrop); setDefaultDropAction(Qt::DropAction::MoveAction);...
ChatGPT AIGC 完成二八分析柏拉图的制作案例
我们先让ChatGPT来总结一下二八分析柏拉图的好处与优点 同样ChatGPT 也可以帮我们来实现柏拉图的制作。 效果如下: 这样的按年份进行选择的柏拉图使用前端可视化的技术就可以实现。 如HTML,JS,Echarts等,但是代码可以让ChatGPT来做,生成。 在ChatGPT中给它一个Prompt …...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
