前端常见的设计模式
说到设计模式,大家想到的就是六大原则,23种模式。这么多模式,并非都要记住,但作为前端开发,对于前端出现率高的设计模式还是有必要了解并掌握的,浅浅掌握9种模式后,整理了这份文章。
六大原则:
-
依赖倒置原则(Dependence Inversion Principle):高层(业务层)不应该直接调用底层(基础层)模块
-
开闭原则(Open Close Principle):单模块对拓展开放、对修改关闭
-
单一原则(Single Responsibility Principle):单模块负责的职责必须是单一的
-
迪米特法则(Law of Demeter):对外暴露接口应该简单
-
接口隔离原则(Interface Segregation Principle):单个接口(类)都应该按业务隔离开
-
里氏替换原则(Liskov Substitution Principle):子类可以替换父类
六大原则也可以用六个字替换:高内聚低耦合。
高层不直接依赖底层:依赖倒置原则
内部修改关闭,外部开放扩展:开闭原则
聚合单一功能:单一原则
低知识接口,对外接口简单:迪米特法则
耦合多个接口,不如隔离拆分:接口隔离原则
合并复用,子类可以替换父类:里氏替换原则
我们采用模式编写时,要尽可能遵守这六大原则
23 种设计模式分为“创建型”、“行为型”和“结构型”

前端九种设计模式

一、创建型
创建型从功能上来说就是创建元素,目标是规范元素创建步骤
1.构造器模式:抽象了对象实例的变与不变(变的是属性值,不变的是属性名)
// 需求:给公司员工创建线上基本信息
// 单个员工创建,可以直接使用创建
const obj = {name:'张三',age:'20',department:'人力资源部门'
}
// 可员工的数量过于多的时候,一个个创建不可行,那么就可以使用构造器模式
class Person {constructor(obj){this.name = obj.namethis.age = obj.agethis.department = obj.department}
}
const person1 = new Person(obj)
2. 工厂模式:为创建一组相关或相互依赖的对象提供一个接口,且无须指定它们的具体类
即隐藏创建过程、暴露共同接口。
// 需求:公司员工创建完信息后需要为每一个员工创建一个信息名片
class setPerson {constructor(obj) {this.pesonObj = obj}creatCard() {//创建信息名片}otherFynction(){}
}
class Person {constructor(obj) {return new setPerson(obj)}
}
const person = new Person()
const card = person.creatCard({name:'张三',age:'20',department:'人力资源部门'
})
3. 单例模式:全局只有一个实例,避免重复创建对象,优化性能
// 需求:判断一款应用的开闭状态,根据不同状态给出不同提示
class applicationStation {constructor() {this.state = 'off'}play() {if (this.state === 'on') {console.log('已打开')return}this.state = 'on'}shutdown() {if (this.state === 'off') {console.log('已关闭')return}this.state = 'off'}
}
window.applicationStation = new applicationStation()
// applicationStation.instance = undefined
// applicationStation.getInstance = function() {
// return function() {
// if (!applicationStation.instance) { // 如果全局没有实例再创建
// applicationStation.instance = new applicationStation()
// }
// return applicationStation.instance
// }()
// }
// application1和application2拥有同一个applicationStation对象
const application1 = window.applicationStation
const application2 = window.applicationStation
二、结构型
结构型从功能上来说就是给元素添加行为的,目标是优化结构的实现方式
1. 适配器模式:适配独立模块,保证模块间的独立解耦且连接兼容
// 需求:一个港行PS,需要适配插座国标
class HKDevice {getPlug() {return '港行双圆柱插头'}
}class Target {constructor() {this.plug = new HKDevice()}getPlug() {return this.plug.getPlug() + '+港行双圆柱转换器'}
}const target = new Target()
target.getPlug()
2. 装饰器模式:动态将责任附加到对象之上
// 说回我们之前说的为公司员工创建名片需求,现在追加需求,要给不同工龄的员工,创建不同的类型名片样式
//由于的工厂函数还有其他各种方法,不好直接改动原工厂函数,这时候我们可以使用装饰器模式实现
class setPerson {constructor(obj) {this.pesonObj = obj}creatCard() {//创建信息名片}otherFynction(){}
}
// 追加
class updatePerson {constructor(obj) {this.pesonObj = obj}creatCard() {this.pesonObj.creatCard()if(this.pesonObj.seniorityNum<1){this.update(this.pesonObj)}}update(pesonObj) {//追加处理}
}const person = new setPerson()
const newPerson = new updatePerson(person)
newDevice.creatCard()
3. 代理模式:使用代理人来替代原始对象处理更专业的事情
// 需求:在单例模式中,我们实现了应用状态的判断,现在,我们需要控制这个应用要在登录注册的情况下才能使用,可以通过代理模式,讲这个需求代理给专门拦截的对象进行判断
class applicationStation {init() {return 'hello'}
}class User {constructor(loginStatus) {this.loginStatus = loginStatus}
}class applicationStationProxy {constructor(user) {this.user = user}init() {return this.user.loginStatus ? new applicationStation().init() : please Login}
}const user = new User(true)
const userProcy = new applicationStationProxy(user)
userProcy.init()
三、行为型
不同对象之间责任的划分和算法的抽象化
1. 观察者模式:当一个属性发生变化时,观察者会连续引发所有的相关状态变更
// 需求:通过智能家居中心一键控制系统
class MediaCenter {constructor() {this.state = ''this.observers = []}attach(observers) {this.observers.push(observers)}getState() {return this.state}setState(state) {this.state = statethis.notifyAllobservers()}notifyAllobservers() {this.observers.forEach(ob => {ob.update()})}
}class observers {constructor(name, center) {this.name = namethis.center = centerthis.center.attach(this)}update() {// 更新状态this.center.getState()}
}
2. 模版模式:在模版中,定义好每个方法的执行步骤。方法本身关注于自己的事情
// 需求:新员工入职,按照规定流程,进行相关培训和办理好员工相关资料
class EntryPath {constructor(obj) {// some code}init() {// 初始化员工信息}creatCard() {// 创建员工名片}inductionTraining() {// 入职培训}trainingExamination() {// 训后测试}personEntry() {this.init()this.creatCard()this.inductionTraining()this.trainingExamination()}
}
3. 命令模式:请求以指令的形式包裹在对象中,并传给调用对象
// 需求:游戏角色的控制
// 接受者
class Receiver {execute() {// 奔跑}
}
// 操控者
class Operator {constructor(command) {this.command = command}run() {this.command.execute()}
}
// 指令器
class command {constructor(receiver) {this.receiver = receiver}execute() {// 逻辑this.receiver.execute()}
}
const soldier = new Receiver()
const order = new command(soldier)
const player = new Operator(order)
player.run()
最后,很多人看了文章后提到了应用场景。本人在实际开发中遇到的场景其实都没办法完全严格按照六大原则来设计代码。但能在认知这些设计模式的情况下设计代码逻辑的思想往这些模式上靠。另外文中很多例子都是比较简单的,一则为了简单理解,二则复杂的不好输出。若大家有优秀的案例可以分享出来,一起交流学习,一起进步~~
相关文章:
前端常见的设计模式
说到设计模式,大家想到的就是六大原则,23种模式。这么多模式,并非都要记住,但作为前端开发,对于前端出现率高的设计模式还是有必要了解并掌握的,浅浅掌握9种模式后,整理了这份文章。 六大原则&…...
OpenAI视频生成模型Sora的全面解析:从ViViT、扩散Transformer到NaViT、VideoPoet
前言 真没想到,距离视频生成上一轮的集中爆发(详见《Sora之前的视频生成发展史:从Gen2、Emu Video到PixelDance、SVD、Pika 1.0》)才过去三个月,没想OpenAI一出手,该领域又直接变天了 自打2.16日OpenAI发布sora以来(其开发团队包…...
3个密码学相关的问题
一、离散对数问题(Discrete Logarithm Problem, DLP) 问题描述:给定 有限阿贝尓群 G中的2个元素a和b,找出最小的正整数x满足:b a ^^ x (或者证明这样的x不存在)。 二、阶数问题(O…...
5G网络eMBB、uRLLC、mMTC
ITU(国际电信联盟)于2015年9月正式定义了5G的三大应用场景:eMBB(增强型移动宽带)、uRLLC(低时延高可靠通信)、mMTC(海量物联网通信)。 eMBB是4G MBB(移动宽带…...
matplotlib图例使用案例1.1:在不同行或列的图例上添加title
我们将图例进行行显示或者列显示后,只能想继续赋予不同行或者列不同的title来进行分类。比较简单的方式,就是通过ax.annotate方法添加标签,这样方法复用率比较低,每次使用都要微调ax.annotate的显示位置。比较方便的方法是在案例1…...
nginx 日志改为json格式
nginx 日志改为json格式 场景描述效果变更旧样式新样式 场景描述 正常使用nginx时,使用默认的日志输出格式,对于后续日志接入其他第三方日志收集、清洗环节,因分隔符问题可能不是很友好。 xxxx - - [19/Feb/2024:11:16:48 0800] "GET …...
【DDD】学习笔记-应用服务
Eric Evans 为运用领域驱动设计的系统架构划定了层次,在领域层和展现层之间引入了应用层(Application Layer):“应用层要尽量简单,不包含业务规则或者知识,而只为下一层(指领域层)中…...
【医学大模型】MEDDM LLM-Executable CGT 结构化医学知识: 将临床指导树结构化,便于LLM理解和应用
MEDDM LLM-Executable CGT 结构化医学知识: 将临床指导树结构化,便于LLM理解和应用 提出背景对比传统医学大模型流程步骤临床指导树流程图识别临床决策支持系统 总结解决方案设计数据收集与处理系统实施临床决策支持 提出背景 论文:https://arxiv.org/p…...
YOLOV8改进系列指南
基于Ultralytics的YOLOV8改进项目.(69.9) 为了感谢各位对V8项目的支持,本项目的赠品是yolov5-PAGCP通道剪枝算法.具体使用教程 专栏改进汇总 二次创新系列 ultralytics/cfg/models/v8/yolov8-RevCol.yaml 使用(ICLR2023)Reversible Column Networks对yolov8主干进行重设计,里…...
FlinkSql一个简单的测试程序
FlinkSql一个简单的测试程序 以下是一个简单的 Flink SQL 示例,展示了如何使用 Flink Table API 和 Flink SQL 进行基本的数据流处理。 定义数据实体 CC : - CC 类表示数据流中的元素,包含两个字段: character (字符&a…...
二、ActiveMQ安装
ActiveMQ安装 一、相关环境二、安装Java8三、下载安装包四、启动五、其他命令六、开放端口七、后台管理 一、相关环境 环境:Centos7.9安装ActiveMQ版本:5.15.9JDK8 二、安装Java8 安装教程:https://qingsi.blog.csdn.net/article/details/…...
通俗易懂的L0范数和L1范数及其Python实现
定义 L0 范数(L0-Norm) L0 范数并不是真正意义上的一个范数,因为它不满足范数的三角不等式性质,但它在数学优化和信号处理等领域有着实际的应用。L0 范数指的是向量中非零元素的个数。它通常用来度量向量的稀疏性。数学上表示为…...
如何在30天内使用python制作一个卡牌游戏
如何在30天内使用python制作一个卡牌游戏 第1-5天:规划和设计第6-10天:搭建游戏框架第11-20天:核心游戏机制开发第21-25天:游戏界面和用户体验第26-30天:测试和发布附加建议游戏类型游戏规则设计界面设计技术选型第6-…...
VsCode指定插件安装目录
VsCode指定插件安装目录 VsCode安装的默认目录是在用户目录(%HomePath%)下的.vscode文件夹下的extensions目录下,随着安装插件越来越多会占用大量C盘空间。 指定VsCode的插件目录 Vscode安装目录: D:\Microsoft VS Code\Code.exeVscode插件安装目录&a…...
解决npm淘宝镜像到期问题
1 背景 由于node安装插件是从国外服务器下载,如果没有“特殊手法”,就可能会遇到下载速度慢、或其它异常问题。 所以如果npm的服务器在中国就好了,于是我们乐于分享的淘宝团队干了这事。你可以用此只读的淘宝服务代替官方版本,且…...
【JAVA】java泛型 详解
java泛型 详解 一、参数化类型(Parameterized Type):二. 泛型类(Generic Class):三. 泛型方法(Generic Method):四. 通配符类型(Wildcard Type)&a…...
基于RBAC的权限管理的理论实现和权限管理的实现
权限管理的理论 首先需要两个页面支持,分别是角色管理和员工管理,其中角色管理对应的是角色和权限的配合,员工管理则是将登录的员工账号和员工所处的角色进行对应,即通过新增角色这个概念,让权限和员工并不直接关联&a…...
Atcoder ABC340 C - Divide and Divide
Divide and Divide(分而治之) 时间限制:2s 内存限制:1024MB 【原题地址】 所有图片源自Atcoder,题目译文源自脚本Atcoder Better! 点击此处跳转至原题 【问题描述】 【输入格式】 【输出格式】 【样例1】 【样例…...
趣学贝叶斯统计:概率密度分布(probability density function)
目录 1. 分布:PDF与PMFPDFPMF 2. 将概率密度函数应用于我们的问题用积分量化连续分布积分度量变化率:导数 3. R语言实践4. 小结 1. 分布:PDF与PMF PDF PDF定义在连续值上。在连续型随机变量的情况下,具体取某个数值的概率是0,因此PDF并不直…...
伦敦金行情分析需要学习吗?
对于伦敦金交易来说,目前大致分成两派,一派是实干派,认为做伦敦金交易重要的是实战,不需要学习太多东西,否则容易被理论知识所局限。另一派则是强调学习,没有理论知识,投资者很难做好伦敦金交易…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...
Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
