前端设计模式

一、为什么前端需要设计模式?

  1. 代码复用:将解决特定问题的方案抽象成模式,可以在不同项目中反复使用。

  2. 解耦:降低代码模块之间的依赖关系,使得修改一个部分时,对其他部分的影响最小。

  3. 提高可维护性:模式化的代码结构清晰,命名规范,易于理解和后续维护。

  4. 提升沟通效率:当团队成员都熟悉设计模式时,说 “我们用单例模式来管理这个全局状态”,比解释一大段代码逻辑要高效得多。

  5. 应对复杂性:大型应用的状态管理、组件通信等问题,都需要成熟的模式来优雅地解决。

二、设计模式分类

前端设计模式主要分为三大类:

  1. 创建型模式:处理对象创建机制

  2. 结构型模式:处理对象组合和关系

  3. 行为型模式:处理对象间的通信和职责分配

三、创建型模式 (Creational Patterns)

        这类模式关注对象的创建过程,旨在提供更灵活、解耦的创建方式主要有单例、工厂、建造者、原型模式

模式

核心思想

前端应用场景

单例模式 (Singleton)

保证一个类只有一个实例,并提供全局访问点。

Vuex/Redux 的 store、全局事件总线、全局缓存、浏览器的 window 对象。

工厂模式 (Factory)

封装对象的创建逻辑,根据条件创建不同类型的对象。

动态组件渲染(根据配置渲染不同组件)、API 请求工厂、表单元素生成器。

建造者模式 (Builder)

将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。

(在前端较少直接使用),但在配置复杂对象时可见其思想。例如,Chart.js 或 ECharts 中配置图表的复杂 options 对象,就是分步构建的。

原型模式 (Prototype)

通过复制现有实例来创建新实例。

JavaScript 本身就是基于原型的语言。Object.create() 是原型模式的直接实现。在需要创建大量相似对象时(如游戏中的敌人),可以通过克隆原型来提高性能。

五、结构型模式 (Structural Patterns)

        这类模式关注类和对象的组合如何将类或对象组合成更大、更灵活的结构目标主要装饰器、代理、适配器、组合、外观等模式。

模式

核心思想

前端应用场景

装饰器模式 (Decorator)

动态地为对象添加新功能,而不改变其结构。

React HOC (高阶组件)、Vue 的 mixins、为按钮添加 loading 状态、为函数添加日志记录功能。

代理模式 (Proxy)

为其他对象提供一种代理以控制对这个对象的访问。

Vue 3 的响应式系统 (reactive/ref) 使用 ES6 Proxy 实现数据劫持。图片懒加载(用一个代理元素占位,等条件满足再加载真实图片)。

适配器模式 (Adapter)

将一个类的接口转换成客户希望的另外一个接口。

封装旧的 API 使其与新的代码库兼容(例如,将一个返回回调的旧 API 封装成返回 Promise 的新 API)。适配不同的第三方库接口。

组合模式 (Composite)

将对象组合成树形结构以表示 “部分 - 整体” 的层次结构。

虚拟 DOM (Virtual DOM) 树就是典型的组合模式。React/Vue 组件树、文件系统结构。

外观模式 (Facade)

为子系统中的一组接口提供一个统一的高层接口,使得子系统更容易使用。

jQuery 就是外观模式的典范,它将复杂的原生 DOM API 封装成简单易用的 $ 接口。封装一个复杂的 localStorage 操作模块,提供简单的 get/set/remove 方法。

六、行为型模式 (Behavioral Patterns)

        这类模式关注对象之间的通信和职责分配,以解决如何更好地分配职责,实现对象间的高效通信为目标。主要有观察者、策略、状态、模板方法、迭代器、职责链模式

模式

核心思想

前端应用场景

观察者模式 (Observer)

定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖者都会收到通知。

DOM 事件监听 (addEventListener)、Vue 的响应式系统、Redux 的订阅发布机制、事件总线 (Event Bus)。

策略模式 (Strategy)

定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换。

表单验证(根据不同字段类型使用不同的验证策略)、动画效果切换(根据用户选择使用不同的动画算法)、排序算法切换。

状态模式 (State)

允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

有限状态机 (FSM)。例如,一个 Tab 组件的状态(active, disabled, hover)及其对应的行为;一个播放器的状态(playing, paused, stopped)及其切换逻辑。

模板方法模式 (Template Method)

在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。

(在前端较少直接使用),但在框架设计中很常见。例如,React 的 Component 类提供了 render() 这个模板方法,子类必须实现它来定义自己的 UI。

迭代器模式 (Iterator)

提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。

JavaScript 的 for...of 循环、数组的 map, filter, reduce 等方法都使用了迭代器模式。Symbol.iterator 是迭代器的核心。

职责链模式 (Chain of Responsibility)

为请求创建了一个接收者对象的链,并沿着这条链传递请求,直到有对象处理它为止。

事件冒泡是职责链模式的绝佳例子。一个事件从目标元素向上传播,直到被某个父元素的监听器处理。在表单验证中,将验证规则串联起来,依次执行。

六、如何学习设计模式

1、从理解问题开始:

        不要为了用模式而用模式。先问自己,“我遇到的是什么问题?” 然后再思考,“哪个模式能优雅地解决这个问题?”

2、从熟悉的框架中寻找:

        现代前端框架本身就是设计模式的集大成者。例如:React 中处处是组件化思想(组合模式)、HOC(装饰器模式)、状态管理(观察者模式)。Vue 的响应式系统(代理模式)、组件通信(观察者模式 / 事件总线)。Redux 是观察者模式和状态模式的完美结合。

3、动手实践:

        尝试用不同的模式解决同一个小问题,对比它们的优劣。例如,实现一个简单的弹窗,可以分别用单例模式和工厂模式来实现,感受它们的不同。

七、写在最后 !!!

  • 不要过度使用:设计模式是为了解决复杂问题的。对于简单的场景,直接编写清晰的代码即可,强行套用模式反而会让代码变得冗余和难以理解。

  • 理解而非背诵:学习模式的核心是理解其背后的设计思想和解决的问题,而不是死记硬背代码实现。

  • 关注现代框架中的模式:许多设计模式已经被现代前端框架(如 React, Vue, Angular)内置或抽象化了。学习这些框架的源码,是深入理解设计模式的绝佳途径

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值