浅谈前端出现率高的设计模式

目录

六大原则:

23 种设计模式分为“创建型”、“行为型”和“结构型”

前端九种设计模式

一、创建型

1.构造器模式:抽象了对象实例的变与不变(变的是属性值,不变的是属性名)

2. 工厂模式:为创建一组相关或相互依赖的对象提供一个接口,且无须指定它们的具体类

3. 单例模式:全局只有一个实例,避免重复创建对象,优化性能

二、结构型

1. 适配器模式:适配独立模块,保证模块间的独立解耦且连接兼容

2. 装饰器模式:动态将责任附加到对象之上

3. 代理模式:使用代理人来替代原始对象处理更专业的事情

三、行为型

1. 观察者模式:当一个属性发生变化时,观察者会连续引发所有的相关状态变更

2. 模版模式:在模版中,定义好每个方法的执行步骤。方法本身关注于自己的事情

3. 命令模式:请求以指令的形式包裹在对象中,并传给调用对象

最后


        说到设计模式,大家想到的就是六大原则,23种模式。这么多模式,并非都要记住,但作为前端开发,对于前端出现率高的设计模式还是有必要了解并掌握的,浅浅掌握9种模式后,整理了这份文章。

        那么,我们先了解六大原则

六大原则:

  • 依赖倒置原则(Dependence Inversion Principle):高层(业务层)不应该直接调用底层(基础层)模块
  • 开闭原则(Open Close Principle):单模块对拓展开放、对修改关闭
  • 单一原则(Single Responsibility Principle):单模块负责的职责必须是单一的
  • 迪米特法则(Law of Demeter):对外暴露接口应该简单
  • 接口隔离原则(Interface Segregation Principle):单个接口(类)都应该按业务隔离开
  • 里氏替换原则(Liskov Substitution Principle):子类可以替换父类

六大原则也可以用六个字替换:高内聚低耦合。

  • 层不直接依赖底层:依赖倒置原则
  • 部修改关闭,外部开放扩展:开闭原则
  • 合单一功能:单一原则
  • 知识接口,对外接口简单:迪米特法则
  • 合多个接口,不如隔离拆分:接口隔离原则
  • 并复用,子类可以替换父类:里氏替换原则

我们采用模式编写时,要尽可能遵守这六大原则

23 种设计模式分为“创建型”、“行为型”和“结构型”

image.png

前端九种设计模式

image.png

一、创建型

创建型从功能上来说就是创建元素,目标是规范元素创建步骤

1.构造器模式:抽象了对象实例的变与不变(变的是属性值,不变的是属性名)

// 需求:给公司员工创建线上基本信息 
// 单个员工创建,可以直接使用创建 
const obj = { name:'张三', age:'20', department:'人力资源部门' 
} 
// 可员工的数量过于多的时候,一个个创建不可行,那么就可以使用构造器模式 
class Person { constructor(obj){this.name = obj.name this.age = obj.age this.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 = state;this.notifyAllobservers();}notifyAllobservers() {this.observers.forEach((ob) => {ob.update();});}
}
class observers {constructor(name, center) {this.name = name;this.center = center;this.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();

最后

        很多人看了文章后提到了应用场景。本人在实际开发中遇到的场景,其实都没办法完全严格按照六大原则来设计代码。但能在认知这些设计模式的情况下,设计代码逻辑的思想往这些模式上靠。另外文中很多例子都是比较简单的,一则为了简单理解,二则复杂的不好输出。若大家有优秀的案例可以分享出来,一起交流学习,一起进步~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/185465.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

scss 实用教程

变量 $ 定义变量 $link-color: blue;变量名可以与css中的属性名和选择器名称相同 使用变量 a {color: $link_color; }$highlight-border: 1px solid $link_color;中划线和下划线相互兼容&#xff0c;即中划线声明的变量可以使用下划线的方式引用&#xff0c;反之亦然。 $li…

CentOS7 安装Jenkins 2.414.3 详细教程

目录 1、前提条件硬件软件-java11安装 2、安装jenkins3、启动jenkins配置用户和用户组配置JAVA_HOME 4、配置Jenkins一直处于启动状态5、测试Jenkins是否可以访问以及配置6、访问Jenkins系统 1、前提条件 硬件 内存 4G ; 硬盘 20G 软件-java11安装 上传文件jdk-11.0.21_lin…

SUSE 12双网卡绑定

原创作者&#xff1a;运维工程师 谢晋 SUSE 12双网卡绑定 客户环境及需求网卡绑定 客户环境及需求 客户一台物理机安装了SUSE 12的操作系统&#xff0c;需要将ETH5和ETH7双网卡聚合为一块虚拟网卡&#xff0c;以保证一块网卡故障不会影响系统正常运行。 网卡绑定 输入命令c…

HCIP---VLAN

文章目录 目录 目录 文章目录 前言 一.VLAN概述 作用&#xff1a; 二.VLAN基础认识 VLAN ID: VLAN端口类别 总结 前言 VLAN技术是现代企业网络和数据中心网络的核心技术之一。本文将重点针对VLAN技术进行详解。 一.VLAN概述 VLAN&#xff08;Virtual Local Area Network…

优雅设计之美:实现Vue应用程序的时尚布局

本文为翻译文章&#xff0c;原文链接&#xff1a; ** https://fadamakis.com/clean-layout-architecture-for-vue-applications-a738201a2a1e 前言 页面布局是减少代码重复和创建可维护且具有专业外观的应用程序的基本模式。如果使用的是Nuxt&#xff0c;则可以提供开箱即用…

C/C++轻量级并发TCP服务器框架Zinx-游戏服务器开发004:游戏核心消息处理 - 玩家类的实现

文章目录 0 代码仓库1 需求2 AOI设计2.1 AOI算法简介2.2 AOI数据结构及实现2.2.1 玩家2.2.2 网格对象2.2.3 游戏世界矩形2.2.4 获取周围玩家的实现2.2.5 代码测试 2.3 GameRole结合AOI创建玩家2.3.1 创建游戏世界全局对象-GameRole继承AOIWorld的Player2.3.2 把玩家到游戏世界的…

oracle-sql语句解析类型

语句执行过程&#xff1a;1. 解析(将sql解析成执行计划) 2.执行 3.获取数据(fetch) 1. shared pool的组成。 share pool是一块内存池。 主要分成3块空间。free&#xff0c; library(库缓存&#xff0c;缓存sql以及执行计划)&#xff0c;row cache(字典缓存) select * from v…

centos7.9 postgresql 16.0 源码安装部署

postgresql 16.0 源码安装部署 环境准备 系统主机名IP地址centos7.9postgres192.168.200.56 软件准备 postgresql-16.0.tar.gz https://ftp.postgresql.org/pub/source/v16.0/postgresql-16.0.tar.gz依赖安装 yum -y install systemd-devel readline readline-devel zlib-devel…

MFC-TCP网络编程服务端-Socket

目录 1、通过Socket建立服务端&#xff1a; 2、UI设计&#xff1a; 3、代码的实现&#xff1a; &#xff08;1&#xff09;、CListenSocket类 &#xff08;2&#xff09;、CConnectSocket类 &#xff08;3&#xff09;、CTcpServerDlg类 1、通过Socket建立服务端&#xff…

Spring Boot + EasyUI Datebox和Datetimebox样例

使用EasyUI的Datebox和Datetimebox组件&#xff0c;并对其进行适当的改造&#xff0c;比如更改日期格式、设置默认值或者将当前时间设置为默认值。 一、运行结果 二、实现代码 1.代码框架 2.实现代码 SpringBootMainApplication.java: package com.xj.main;import org.spri…

μC/OS-II---内核:多任务与调度

目录 内核&#xff1a;多任务&#xff08;ucos_ii.h文件的函数&#xff09;Task创建Task创建&#xff08;扩展&#xff09;Task删除/请求删除Task改变Task优先级Task挂起和恢复Task信息获取Task调度器上锁和开锁 内核&#xff1a;调度&#xff08;oc_core.c文件的函数&#xff…

MySQL系列-win10安装MySQL

MySQL系列-win10安装MySQL 1. MySQL系列-win10安装MySQL1.1MySQL下载安装MySQL5.71.2MySQL下载再安装MySQL8.0 未完待续 1. MySQL系列-win10安装MySQL 1.1MySQL下载安装MySQL5.7 下载地址 https://www.mysql.com/downloads/ 进入后&#xff0c;下拉页面&#xff0c;最下面有社…

搜款网VVIC商品详情API接口

搜款网VVIC商品详情接口提供了全面的API接口&#xff0c;通过该接口&#xff0c;开发者可以使用商品ID等参数请求API&#xff0c;获取商品的详细信息&#xff0c;如商品标题、描述、价格、库存状态、销售量等。 要使用VVIC商品详情接口&#xff0c;您需要先注册开发者账号并申…

每天一点python——day65

#每天一点Python——65 #字符串的内容对齐操作类似于word中左对齐、右对齐、居中对齐如图 #例&#xff1a; s1hello,python print(s1.center(20,*))#设置宽度20&#xff0c;填充图是*s1有12个字符&#xff0c;这个字符串的宽度设置为20&#xff0c; 20-128 因为center是居中对齐…

【唠唠嵌入式】__嵌入式开发需要从0开始造轮子吗?

目录 前言 从0开始和套用模板的利弊 1. 从0开始的利弊 2. 套用模板的利弊 从0开始&#xff0c;还是套用模板&#xff1f; 1. 看项目赶不赶 2. 看项目用途 3. 看工程师水平 4. 看领导决策 5. 看公司决策 6. 看项目规划 实际工作 总结 (*&#xffe3;︶&#xffe3…

java数据结构--双端队列

一.概念 双端队列的意思是可以在头部和尾部添加和删除元素&#xff0c;更一般的单向链表队列比起来更加的灵活&#xff0c;下面我们用双向循环带哨兵链表和数组来分别实现 二.定义接口Dequeue /*** 双端队列*/ public interface Dequeue<E> {//队头添加元素boolean off…

QT QStackedWidget

QStackedWidget是一个特殊的布局容器&#xff0c;它可以管理多个页面&#xff0c;并且只能显示其中一个页面。这些页面是QWidget或其派生类的实例&#xff0c;并通过调用addWidget()函数添加到堆栈中。 例如&#xff1a; #include <QWidgets> #include <QStackedWid…

10.(vue3.x+vite)组件间通信方式之props与$emit

前端技术社区总目录(订阅之前请先查看该博客) 示例效果 父组件代码 <template><div><div>{{message }}</div><Child

Scala爬虫实战:采集网易云音乐热门歌单数据

导言 网易云音乐是一个备受欢迎的音乐平台&#xff0c;汇集了丰富的音乐资源和热门歌单。这些歌单涵盖了各种音乐风格和主题&#xff0c;为音乐爱好者提供了一个探索和分享音乐的平台。然而&#xff0c;有时我们可能需要从网易云音乐上获取歌单数据&#xff0c;以进行音乐推荐…

【Azure 架构师学习笔记】-Azure Storage Account(5)- Data Lake layers

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Storage Account】系列。 接上文 【Azure 架构师学习笔记】-Azure Storage Account&#xff08;4&#xff09;- ADF 读取Queue Storage 前言 不管在云还是非云环境中&#xff0c; 存储是IT 系统的其中一个核心组件。在…