当前位置: 首页 > news >正文

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());

在这里插入图片描述


🎉🎉本篇小结

简单工厂模式和抽象工厂模式都隶属于设计模式中的 创建型模式

简单工厂模式是 由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。

抽象工厂模式是指 当有多个抽象角色时使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象。

建造者模式 将一个复杂对象的构建层与其表示层相互分离,同样的构建过程可采用不同的表示。工厂模式主要是为了创建对象实例或者类簇(抽象工厂),关心的最终产出的是什么,而不关心创建的过程。而建造者模式关心的是创建这个对象的整个过程,甚至于创建对象的每一个细节。

好啦,本篇文章到这里就要和大家说再见啦,祝你这篇文章阅读愉快,你下篇文章的阅读愉快留着我下篇文章再祝!


参考资料:

  1. 菜鸟教程 · 抽象工厂模式
  2. 百度百科 · 简单工厂模式,抽象工厂模式
  3. 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个行业、数千家企业,支持数百万设备及应用。 在本文中&#xff0…...

解决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…...

智慧排水监测系统,科技助力城市排水治理

城市里,人们每天通过道路通行,人多,路窄,都会拥堵。同样,下雨天,雨水通过雨篦汇集、管道输送,最终排出去,当雨水过大,或者管道过窄,或者管道不通畅&#xff0…...

部署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 …...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

OpenLayers 分屏对比(地图联动)

注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...