你必须要会的4种Web前端设计模式

article/2025/10/22 16:16:56

在软件工程领域,设计模式是为了解决特定问题而产生的一些可复用的方法、模板。每一种设计模式都针对性解决某一类场景的问题。设计模式被认为是开发者解决通用问题的最佳实践。

通常我们学习的设计模式,大多数与面向对象的语言相关,比如Java。市面上大部分关于设计模式的书籍也是基于面向对象来进行讲解的。但对于大部分平常写JavaScript的开发者来说,面向对象的设计模式基本上是用不着的,如果不仔细思考,会经常错误或过度使用设计模式,不仅增加了软件开发成本,还加重了后期维护的负担。作为以Javascript为主语言的开发者,有必要认真审视设计模式与JavaScript语言之间的关系,以及如何将设计模式与JavaScript更紧密的结合起来,使得设计模式带来真正的收益。

本篇文章将会从以下三点来谈谈Web前端中的设计模式

  • 设计模式三问
  • 四种常用设计模式解析
  • 误区

设计模式三问

what:什么是设计模式

上半年由于全国乃至全世界届疫情的原因,口罩数量缺口巨大,因此口罩价格也疯涨了十几倍,这吸引了一大批老板加入口罩生产的行业。有的传统企业主将原本用于生产其他产品的车间改为生产口罩的,有的则是三五好友凑一笔钱临时建一个生产厂地。那么问题来了,为什么这些人都能在短时间内完成工厂的建设或改造呢?原因是,针对生产口罩这么一个场景,整个过程已经完全规范和自动化了,比如有的机器负责布料成型,有的负责多层压制,有的负责消毒。这就是模式,解决某一类问题的特定解决方法。

why:为什么会有设计模式?

“其实地上本没有路,走的人多了,也便成了路”。

在软件工程初期,需求相对较简单的时候,是没有设计模式这一说的。但随着时间推移,需求变得原来越复杂,遇到的问题也就越来越多。这些问题中很多都有相似性,慢慢的开发者们也根据不同的问题总结出了一套解决的方法论,并给它们取一个通俗易懂的名字,就是设计模式了,比如“工厂模式”、“观察者模式”等等。

why:为什么要用设计模式?

来打个比方,想必大家对下面三个小地图都比较熟悉吧?

想象一下,当地图上一个敌人的头像都看不见的时候,你方队伍一般情况下会怎么做?缩回高低还是抱团蹲人?无论选择哪种策略,都是在按照一种模式在进行,这些模式就是为了在地图上看不见敌方时能更好的应对而产生的解决方案。所以,用设计模式,是为了遇到相似的问题、场景时,能快速找到更优的方式解决。

how:怎么用设计模式

为了更方便、更快速的找到你想要的东西,往往你会把房间整理的井井有条。但整理是需要花时间和精力的,如果这个房间你根本就不常进去,里面的东西也不需要经常挪用,那其实并没有必要整理成这样。这些消耗的时间和精力,对应到软件工程中就是软件成本。在用设计模式时,必须要衡量其所带来的的收益,如果为了一段日后都大概率不会变动的代码采用过多的设计模式来编写,其实是得不偿失的。所以,在用设计模式前,我们需要慎重思考哪些功能是日后可能会变的,哪些不会。

 

四种常用设计模式解析

上图应该是大家在各类书籍中常见到的设计模式,但其中很大一部分在实际需求开发中使用频率不高,所以我根据个人经验从中摘取了四个比较常用的模式来进行讲解。

 

1.策略模式+组合模式

场景:

在一个设备管理系统中,当用户只有全部满足如下条件时,才能看到设备申请界面,有权限申请设备

  • A公司员工
  • B事业部
  • C技术栈
  • 部分经理

拿起键盘我们就开始写代码,会写成如下这样

这种写法有什么问题呢?

1.当条件越来越多时,checkAuth函数会越来越长,可读性以及可维护性相当的差。上面例子中,省略了具体判断中的处理代码,如果每个分支的处理代码都不少,那整个checkAuth函数最后会变得非常复杂。

2.每个判断其实都是独立的策略,假设有一天产品经理提了一个新需求,要做一个请假审核模块,也必须得是A公司+部门经理才能看到,那你就必须得从这个checkAuth函数中copy对应的处理分支过去了,这样项目中就又多了一块一模一样的代码。更进一步,后面产品经理要对判断公司这个分支的处理细节都要改进时,那你就不得不在多处进行修改,麻烦且不说,改漏了就会产生一个BUG。

对于模式较为单一的策略,其实只需要将策略的实现逻辑抽离即可,无需更复杂的写法

但是对于较为灵活的场景,需要策略之间的灵活组合来完成需求,就得使用策略模式+组合模式了。

比如,设备申请模块需要ABCD四个权限,而请假审核模块只需要BC权限,这时authStrategy就不再适用了,需要更灵活的写法。

通过这种动态添加策略的写法,只需要对不同场景配置不同的策略集,就能灵活的处理设备申请模块和请求审核模块的权限判断了。总结来看,当你负责的模块满足以下三个条件时,就建议用策略+组合模式

  • 各判断条件下的策略相互独立且可复用
  • 策略内部逻辑相对复杂
  • 策略需要灵活组合

 

代理模式

场景:

在系统中通过接口查询某日的统计数据,并期望能在前端对查询过的日期进行缓存,当下次请求时如果日期命中对应缓存,则直接返回缓存数据,不向后台发起请求。

直接写我们会写成下面这样

如果需求只是一处这样,那没什么问题,这样写最直接最简单。但我们得考虑到,系统中其他地方的请求,是否也是需要通过参数来缓存请求结果的?如果是,那么就需要改造上面的代码,用代理模式来让这种缓存逻辑更加通用。

上面代码通过通用的cacheRequest函数来代理真正的请求。cacheRequest函数利用闭包,将传入的请求函数与cacheDataMap锁定在一个作用域中,并返回一个增强后的请求函数。这样,其他需求如果也有类似的缓存需求,那就可以直接用cacheRequest函数去生成一个即可。

总结来看,当你负责的两个模块职责比较单一且可复用,并且两个模块间的存在整合、限制、过滤等关系时,可以尝试使用代理模式。

这里提一个思考问题,React中的HOC属于代理模式吗?

发布订阅模式

场景:

还是上面有提到过的设备申请模块,现在你要实现一个设备申请功能,需求要求申请成功后,会分别触发供应商订单生成,相关方消息通知,审核人审核三块的逻辑,调用逻辑如下图。

 

比较直接的代码写法是

这样写可能会有什么问题呢?当这三个模块不是你写的,而是分工到不同的开发者去完成时,你会发现麻烦有点大。

1.依赖模块的方法可能会改变,比如MessageCenter的开发者并没有遵照约定,把fetch方法改成了request,那执行的时候就报错了。

2.当你在写设备申请的onSubmitSuccess函数的时候,需求只依赖函数中这三个模块,但随着业务发展,你需要调用的模块在增加,这时你就不得不再次找到这个onSubmitSuccess函数往里面添加依赖项。

3.当你在写设备申请的onSubmitSuccess函数的时候,你并不知道要调用哪些模块,因为这些开发不是同时进行的。所以你无法再函数中预知要写哪些,必须得等到相关模块完成后再来填充调用代码。

基于这些问题的考虑,我们必须让程序更灵活一些。在写onSubmitSuccess函数的时候,我们只需要考虑结束时发通知出去告知申请成功,至于谁需要这个消息做什么并不需要关系。借助发布订阅模式,可以很轻松的实现这种效果。

总结来看,当你负责的模块,满足

  • 各模块相互独立
  • 存在一对多的依赖关系
  • 依赖模块不稳定、依赖关系不稳定
  • 各模块由不同的人员、团队开发

的条件时,建议使用发布订阅模式来进行开发。

思考一下,Redux是否使用了发布订阅模式呢?

 

责任链模式

场景:

假设在设备申请流程的需求中,需要经过三个逻辑模块

  1. 申请设备
  2. 选择收获地址
  3. 选择审核人

一般的写法是

当流程需求变得多样化时,这段代码就无法适应变化了,我们假设以下场景。

1.新流程申请软件license需要复用选择审核人逻辑。

在这种需求下,原有代码中审核人的代码无法复用,因为selectChecker函数依赖了处理具体提交业务的submitApply代码。要么copy修改,要么重新一份。

 

2.申请设备流程需要增加一个检查库存的环节。

在这种需求下,需要改动applyItDevice方法,增加检查库存逻辑才能满足。

如果我们使用责任链模式进行改造,那么这些场景都能更好的满足。

利用责任链模式,可以很轻松的复用每一个流程的逻辑,并且按需要组合成新的流程。

总结来看,当你负责的模块,满足

  • 你负责的是一个完整流程,或你只负责流程中的某个环节
  • 各环节可复用
  • 各环节有一定的执行顺序
  • 各环节可重组

时,建议使用责任链模式。

 

误区

“当我们有一把锤子,看什么都是钉子”

设计模式就好比一把锤子,当我们手握锤子的时候,不能看什么都是钉子,在写代码时,也不能处处都使用设计模式。使用设计模式本身是需要成本的,我们需要根据具体的场景来进行判断。正如开头所讲,识别变化与不变化的地方是核心关键点。

 


http://chatgpt.dhexx.cn/article/ltl7iBgZ.shtml

相关文章

前端开发中常用的几种设计模式

设计模式概览 设计模式是对软件设计开发过程中反复出现的某类问题的通用解决方案。设计模式更多的是指导思想和方法论,而不是现成的代码,当然每种设计模式都有每种语言中的具体实现方式。学习设计模式更多的是理解各种模式的内在思想和解决的问题&#…

图像金字塔原理

一、图像缩小 先高斯模糊,再降采样,需要一次次重复,不能一次到底 二、图像扩大 先扩大,再卷积或者使用拉普拉斯金字塔 三、金字塔类型 1、高斯金字塔 用于下采样。 高斯金字塔是最基本的图像塔。 原理:首先将原图…

【编程】金字塔图案

1.问题描述 打印出金字塔图案,如图1.1所示。 图1-1 2.问题分析 这个问题是一个很经典的循环应用的题目。我们都知道,打印输出的时候,都是从最左端输出,而这里,第一个星号是在中间。这实际是…

计算机视觉-OpenCV图像金字塔

😊😊😊欢迎来到本博客😊😊😊 本次博客内容将继续讲解关于OpenCV的相关知识 🎉作者简介:⭐️⭐️⭐️目前计算机研究生在读。主要研究方向是人工智能和群智能算法方向。目前熟悉pytho…

图像金字塔(image pyramid) 分为两种:高斯金字塔  和  拉普拉斯金字塔。

高斯金字塔 高斯金字塔模仿的是图像的不同的尺度,尺度应该怎样理解?对于一副图像,你近距离观察图像,与你在一米之外观察,看到的图像效果是不同的,前者比较清晰,后者比较模糊,前者比…

数字图像处理:图像金字塔

转载请标明出处:数字图像处理:图像金字塔_数字图像处理opencv_新浪博客 (一)概念 以多个分辨率来表示图像的一种有效且概念简单的结构是图像金字塔。图像金字塔最初用于机器视觉和图像压缩,一个图像金字塔是一系列以金…

图像处理-图像金字塔

图像金字塔(image pyramid),一般有两种:高斯金字塔、拉普拉斯金字塔 ——————————————————————————————— 先介绍下里面的一些操作: 下采样:相当于对图像进行一个像素的抽取&a…

10.图像金字塔

图像金字塔:主要是指一种算法思想 一般情况下,我们要处理是一副具有固定分辨率的图像。但是有些情况下,我们雪要对同一图像的不同分辨率的子图像进行处理。比如,我们要在一幅图像中查找某个目标,比如险,我们…

图像金字塔:概念及实现

文章目录 图像金字塔:概念和实现1. 图像金字塔的概念2. 图像金字塔的实现方式3. 基于OpenCV的图像金字塔实现参考资料 图像金字塔:概念和实现 首先补充一下分辨率的概念:图像分辨率指图像中存储的信息量,是每英寸图像内有多少个像…

图像金字塔的简单理解

图像金字塔模型: Level层定义的是图片的分辨率,图像金字塔的塔底到塔顶表示的是图片的缩小过程。也就是说从第Level0层开始是原图,越往上越压缩,丢失的信息越多。 图像金字塔的测试: 图片: halcon代码&am…

数字图像处理5:图像金字塔

图像金字塔 近似金字塔和残差金字塔 图像金字塔是图像中多尺度表达的一种,最主要用于图像的分割,是一种以多分辨率来解 释图像的有效但概念简单的结构。图像金字塔最初用于机器视觉和图像压缩,一幅图像的金字塔是一系列以金字塔形状排列的分…

图像金字塔、特征金字塔(FPN)

图像金字塔 参考: https://www.jianshu.com/p/436e96200f80 图像金字塔是图像多尺度表达的一种,是一种以多分辨率来解释图像的有效但概念简单的结构。一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低,且来源于同一张原始图的图像…

图像金字塔,原理、实现及应用

什么是图像金字塔 图像金字塔是对图像的一种多尺度表达,将各个尺度的图像按照分辨率从小到大,依次从上到下排列,就会形成类似金字塔的结构,因此称为图像金字塔。 常见的图像金字塔有两类,一种是高斯金字塔&#xff0…

计算机视觉教程2-5:图像金字塔送她一朵玫瑰(附代码)

目录 1 金字塔2 什么是图像金字塔?3 图像金字塔有什么用?4 OpenCV实战图像金字塔 1 金字塔 平时你听到、见到的金字塔是什么样的? 这样? 还是这样? 实际上除了这些,还有图像金字塔 图像金字塔有什么用&am…

图像金字塔(Python实现)

图像金字塔(Python实现) 1 简介 在图像处理中常常会调整图像大小,最长的就是放大(zoom in)和缩小(zoom out),尽管集合变换也可以实现图像放大或者缩小 一个图像金字塔式一系列的图像组成,最底下一张式图像尺寸最大,最上方的图像尺寸最小,从空间上从上向下…

图像金字塔分层算法

一. 图像金字塔概述 欢迎关注微信公众号“智能算法”! 1. 图像金字塔是图像中多尺度表达的一种,最主要用于图像的分割,是一种以多分辨率来解释图像的有效但概念简单的结构。 2. 图像金字塔最初用于机器视觉和图像压缩,一幅图像的金…

图像金字塔是什么?

一般情况下,我们要处理是一副具有固定分辨率的图像。但是有些情况下,我们需要对同一图像的不同分辨率的子图像进行处理。比如,我们要在一幅图像中查找某个目标,比如脸,我们不知道目标在图像中的尺寸大小。这种情况下&a…

图像处理之高斯金字塔

一:图像金字塔基本操作 对一张图像不断的模糊之后向下采样,得到不同分辨率的图像,同时每次得到的 新的图像宽与高是原来图像的1/2, 最常见就是基于高斯的模糊之后采样,得到的 一系列图像称为高斯金字塔。 高斯金字塔不同(DoG)又…

【OpenCV学习笔记】之图像金字塔(Image Pyramid)

一、尺度调整 顾名思义,即对源图像的尺寸进行放大或者缩小变换。在opencv里面可以用resize函数,将源图像精准地转化为指定尺寸的目标图像。要缩小图像,一般推荐使用CV_INETR_AREA(区域插值)来插值;若要放大图像,推荐使…

图像金字塔总结

本文转载自: http://blog.csdn.net/dcrmg/article/details/52561656 一、 图像金字塔 图像金字塔是一种以多分辨率来解释图像的结构,通过对原始图像进行多尺度像素采样的方式,生成N个不同分辨率的图像。把具有最高级别分辨率的图像放在底…