第四节 前端设计模式 | 字节青训营笔记

238 阅读8分钟

设计模式概念

这是我参与「第四届青训营 」笔记创作活动的的第4天!

本次的课程内容就比较偏概念化了,主要介绍了前端设计模式的一些内容和应用,话不多说,我们先来聊聊什么是设计模式吧。

设计模式简单来说就是:软件设计中常见问题的解决方案模型。其来源主要有两个方面,一个是历史相关经验的总结,另一个是解决方案模型。设计模式不是只局限于某种特定语言,它不是一种特定具象的模型,而是一种思想和想法,是一种模式。

设计模式的起源和发展经过了漫长的时间,最早这一概念被应用于1977年的建筑工程书籍《建筑模式语言》,其分析了建筑和城镇建立了关于规划和建筑的模式语言理论体系,提供了253个经典建筑和构造的模式,是最早的设计模式理念。而软件开发领域对于设计模式一个正式的定义是在1994年的面向对象软件基础书籍《设计模式:可复用面向对象软件的基础》,该书中一段关于三大类型设计模式的描述被计算机专业人员评为经典。

image.png

“创建型类模式将对象的部分创建工作延迟到子类,而创建型对象 模式则将它延迟到另一个对象中;结构型类模式使用继承机制来组 合类,而结构型对象模式则描述了对象的组装方式;行为型类模式 使用继承描述算法和控制流,而行为型对象模式则描述了一组对象 怎样协作完成单个对象所无法完成的任务。” 这段话完美的诠释了设计模式的任务,感兴趣的朋友可以去看看。

设计模式分类

设计模式一共有23种,主要分为以下三种类型:

  • 创建型:主要偏向于高效,灵活的创建一个对象来使用。
  • 结构型:将创建好的对象灵活的组建成较大合理的结构。
  • 行为型:主要负责各个对象之间的高效通信和职责划分。

image.png

浏览器中的设计模式

浏览器中主要使用的设计模式为:单例模式和发布订阅模式。

1.单例模式:

其定义是全局唯一访问对象,应用于缓存,全局状态管理等场景。具体的我们可以看使用单例模式实现请求缓存的案例。 image.png

在以上代码实例中,我们定义了Request请求类,在类中使用静态方法instance来存储全局唯一实例, 创建缓存的对象,同时初始化我们的缓存内容,在11行到第19行,我们实现单例模式,通过request调用getInstance来创建对象,并作一个判定。然后定义两个test方法,分别处理没有缓存和有缓存的情况,同样使用request调用getInstance来创建对象,完成缓存调用的判定,而以上的案例就是一个传统的单例模式的应用。

2.发布订阅模式:

其定义为一种订阅机制,可在被订阅对象发生变化时通知订阅者,主要应用于系统架构之间的解耦,业务中一些实现模式,例如:邮件订阅,上线订阅,发布订阅等功能,该模式应用广泛。

但发布订阅模式并不在23种设计模式之中,它早期只是观察者模式的一种别名,主要因为观察者模式中对象之间一对多依赖关系的特性,使得其在发布订阅功能方面广泛使用,经过长时间的开发和沉淀,发布订阅已经独立于观察者模式,成为一种不同的设计模式。其主要区别在于角色的变化,观察者模式有两个和重要的角色,即目标和观察者,而发布订阅模式中,多了一个事件通道的角色,事件通道作为调度中心去管理事件的发布和订阅工作,即目标在触发事件时,无需再亲自去通知所有的观察者,目标和观察者的依赖关系被事件通道所隔绝开来。对详细区别感兴趣的朋友可以看这个链接:[观察者模式与订阅发布模式的区别 - 一像素 - 博客园 (cnblogs.com)],而具体的结构图如下。

image.png

关于发布订阅模式,我们通过分析用户上线订购功能来分析。

image.png

首先我们定义一个User类,包含name和status还有followers三个属性,分别代表用户名和在线状态以及订阅了此用户的其他用户,同时初始化一个其他订阅用户的数组,定义一个subscribe方法用于订阅其他用户,再定义一个online方法,通过this改变自己上线的状态,同时调用订阅函数通知订阅自己的人(followers),到这我们就完成了一个用户上线的定义类。

image.png

接着我们写一个test方法,创建新的用户,并且用user1和user2去订阅user3,并传入用户函数,使用user3调用上线的方法,触发上线通知的方法去通知user1和user2,到这里,我们就完成了发布订阅模式的应用。

JavaScript中的设计模式

JS中对于设计模式的应用也比较广泛,其主要应用的有三种模式,分别是原型模式,代理模式和迭代器模式,同时JS中提供的API可以帮助我们实现这几种模式。

  1. 原型模式:其定义为复制已有对象来创建新的对象,应用场景是我们比较常见的JS中对象创建的基本模式。
  2. 代理模式:可自定义控制原对象的访问方式,并且允许在更新前后做一些额外处理,应用场景主要有监控,代理工具,前端框架实现等等。
  3. 迭代器模式:在不暴露数据类型的情况下访问集合中的数据,应用场景的代表为数据结构中多种数据类型的操作接口,比如列表,树等。

前端框架中的设计模式

前端架构方面我们主要使用的有两种模式,分别是代理模式和组合模式,这里提到的代理模式与我们上文在JS中提到的代理模式会有些不同,下面我们具体来看前端框架中对DOM操作的代理。

image.png

我们在更改DOM属性的时候,其实页面的显示只更新一个虚拟的DOM,真正对DOM的操作是通过代理,我们更新的是被代理操作过的DOM,在页面更新的过程中,就是一个代理的体现。

组合模式的定义为:可多个对象组合使用,也可单个对象独立使用,其应用场景主要有:DOM,前端组件,文件目录,部门等类似的场景,这里我们主要来看React的一个组件结构。 image.png

我们要实现一个count,其实现方式如上图,我们可以看到所有的count都不需要我们自己去调用,而是它自己完成的,我们在调用setCount的时候会设置一个队列,这里对整个DOM作一个代理操作。

image.png

作为一个count,它可以被独立的渲染,也可以在更大的一个结构中进行渲染,如上图,count和header还有footer共同在一个更大的结构中,count作为其中的一部分和整个APP进行一个渲染,这就是一个组合模式的案例。

总结

image.png 设计模式在我们日常开发中都有不同的应用,在中国的发展也比较热门,在2014年更是达到了一个顶峰,但设计模式的应用和发展趋势是日益降低的,其主要原因在于开发技术的不断发展以及编程范式,响应式编程的应用,设计模式在一些开发和功能实现上以及有些力不从心。但设计模式的思想对于我们开发人员和学习编程思想的小白依旧非常具有参考价值,设计模式是没办法完美满足开发需求和应用场景的,但是我们可以结合设计模式的思想和现代编程语言的可能性去完成一些复杂的业务需求,并不断拓展自己的实践经验。

今天的笔记分享就到这里啦!

参考文献

[1]百度百科.《建筑模式语言》[OL].baike.baidu.com/item/建筑模式语言

[2]Erich Gamma,Richard Helm,Ralph Jo.《设计模式:可复用面向对象软件的基础》[M].机械工业出版社,2007,01-02:10-15.

[3]一像素.《观察者模式与订阅发布模式的区别》[OL].观察者模式与订阅发布模式的区别 - 一像素 - 博客园 (cnblogs.com)博客园,设计模式,2019,05-03.