前端常见的设计模式
说到设计模式,大家想到的就是六大原则,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并不直…...

伦敦金行情分析需要学习吗?
对于伦敦金交易来说,目前大致分成两派,一派是实干派,认为做伦敦金交易重要的是实战,不需要学习太多东西,否则容易被理论知识所局限。另一派则是强调学习,没有理论知识,投资者很难做好伦敦金交易…...

Java实现停车场收费系统 JAVA+Vue+SpringBoot+MySQL
目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 停车位模块2.2 车辆模块2.3 停车收费模块2.4 IC卡模块2.5 IC卡挂失模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 停车场表3.2.2 车辆表3.2.3 停车收费表3.2.4 IC 卡表3.2.5 IC 卡挂失表 四、系统实现五、核心代码…...

服务器遭受 DDoS 攻击的常见迹象有哪些?
服务器遭受 DDoS 攻击的现象很常见,并且有时不容易预防,有部分原因是它们的形式多种多样,而且黑客手段越来越隐蔽。如果您怀疑自己可能遭受 DDoS 攻击,可以寻找多种迹象。以下是 DDoS 攻击的5个常见迹象: 1.网络流量无…...

【机器学习笔记】 15 机器学习项目流程
机器学习的一般步骤 数据清洗 数据清洗是指发现并纠正数据文件中可识别的错误的最后一道程序,包括检查数据一致性,处理无效值和缺失值等。与问卷审核不同,录入后的数据清理一般是由计算机而不是人工完成。 探索性数据分析(EDA 探索性数据…...

【C语言】位操作符与移位操作符练习
目录 前言: 1.一道变态的面试题 2.输入一个整数 n ,输出该数32位二进制表示中1的个数。其中负数用补码表示。 方法一: 方法二: 方法三: 3.打印整数二进制的奇数位和偶数位 前言: 前篇我们学习过C语言…...

第十四届“中关村青联杯”全国研究生数学建模竞赛-A题:无人机在抢险救灾中的优化运用
目录 摘 要: 1 问题重述 1.1 问题背景 1.2 待解决的问题 2 模型假设及符号说明...

Android 9.0 Launcher3桌面显示多个相同app图标的解决办法
1.前言 在9.0的系统ROM定制化开发中,在Launcher3的系统原生桌面中,在显示桌面的时候,在禁用和启用app的功能测试的时候,会发现有多个相同app的图标显示在桌面 这对Launcher3的体验效果不是很好,所以为了优化产品,需要解决这个bug,然后让产品更完善 2.桌面显示多个相同…...

WordPress主题YIA在广告位添加图片广告时下方有空白怎么办?
YIA主题设置中默认有4个广告位,而侧边栏的广告位由站长自行添加。boke112百科在这些广告位添加图片广告后发现图片下方有空白,导致下方的两个角没有变圆角,看起来也有点不好看。具体如下图所示: 其实,这个问题就是典型…...

5.15 BCC工具之kvm_hypercall.py解读
一,工具简介 在该示例中,我们可以了解到如何使用eBPF(扩展BPF,Berkeley Packet Filter的扩展)和bcc(BPF Compiler Collection)来分析KVM(Kernel-based Virtual Machine)中的超级调用(hypercall)。 即当exit_reason为VMCALL时,有状态的kvm_entry和kvm_exit记录以及…...

git 解除本地分支与其它分支(远程分支)的关联
开发中,我在同事的分支开一条分支,并将同事的分支作为关联分支,前两天还好,我一个人在干活,然而第3天,同事回来了,他在他那条分支也开发,这时就会出现2种情况, 1. 同时修…...

conda 所有的命令及其讲解
Conda 是一个开源的包管理器和环境管理器,可以用于安装、运行和升级跨平台的软件包和环境。Conda 很流行于数据科学、机器学习、科学计算等领域,因为它能够快速地安装、管理和部署软件包和环境。以下是 Conda 的一些主要命令及其简要说明: 环…...