Skip to content

前端常用设计模式

设计模式参考

设计模式是软件开发中解决特定问题的成熟方案。在前端开发中,合理使用设计模式可以提高代码的可维护性、可扩展性和复用性。虽然经典的 GoF 设计模式有 23 种,但在前端开发中,部分模式的使用频率远高于其他模式。以下是较为完整的列表。

1. 创建型模式 (Creational Patterns)

关注对象的创建过程,将对象的创建和使用分离。

1.1 单例模式 (Singleton)

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

  • 前端场景: Vuex/Redux Store, 全局 Modal/Toast, Axios 实例。
javascript
class Singleton {
  static instance = null;
  constructor() {
    if (Singleton.instance) return Singleton.instance;
    Singleton.instance = this;
  }
}

1.2 工厂模式 (Factory Method)

定义一个用于创建对象的接口,但让子类决定实例化哪一个类。

  • 前端场景: React.createElement, 根据配置生成不同类型的图表/组件。

1.3 抽象工厂模式 (Abstract Factory)

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

  • 前端场景: 跨平台 UI 库(同时生成 Web, iOS, Android 的组件套件),换肤功能(生成一整套主题相关的组件)。

1.4 建造者模式 (Builder)

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

  • 前端场景: 构建复杂的 DOM 结构,复杂的 Webpack/Vite 配置对象生成器。
javascript
// 链式调用构建
new DialogBuilder()
  .setTitle("提示")
  .setContent("内容")
  .setConfirm("确定")
  .build();

1.5 原型模式 (Prototype)

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

  • 前端场景: Object.create, JS 原型链继承。

2. 结构型模式 (Structural Patterns)

关注对象和类的组合。

2.1 代理模式 (Proxy)

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

  • 前端场景: Vue 3 响应式, 跨域代理, 图片懒加载, 缓存代理。

2.2 装饰器模式 (Decorator)

动态地给一个对象添加一些额外的职责。

  • 前端场景: HOC (高阶组件), ES7 Decorators, AOP 日志/埋点。

2.3 适配器模式 (Adapter)

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

  • 前端场景: 接口格式转换 (后端字段 -> 前端组件 Props), Axios 适配 Node/Browser 环境。

2.4 外观模式 (Facade)

为子系统中的一组接口提供一个一致的界面,定义一个高层接口,这个接口使得这一子系统更加容易使用。

  • 前端场景: 统一兼容层 (如 jQuery 对 DOM 操作的封装), 封装复杂的图表库调用。

2.5 桥接模式 (Bridge)

将抽象部分与它的实现部分分离,使它们都可以独立地变化。

  • 前端场景: 比如事件处理中,将业务逻辑(抽象)和事件回调(实现)分离,便于复用。

2.6 组合模式 (Composite)

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

  • 前端场景: 虚拟 DOM 树, UI 组件树, 文件夹目录结构。

2.7 享元模式 (Flyweight)

运用共享技术有效地支持大量细粒度的对象。

  • 前端场景: 列表渲染优化 (复用 DOM 节点), 事件委托 (所有子元素共享一个事件监听器)。

3. 行为型模式 (Behavioral Patterns)

关注对象之间的通信。

3.1 观察者模式 (Observer)

一对多依赖,当对象状态改变时,通知所有依赖者。

  • 前端场景: DOM 事件, Vue 2 Dep/Watcher

3.2 发布-订阅模式 (Publish-Subscribe)

  • 前端场景: EventBus, EventEmitter, 跨组件通信。

3.3 策略模式 (Strategy)

定义一系列算法,封装并可替换。

  • 前端场景: 表单验证规则, 不同的缓动函数, 支付方式选择。

3.4 状态模式 (State)

允许对象在内部状态改变时改变行为。

  • 前端场景: 有限状态机 (FSM), Promise 状态流转, 游戏角色状态。

3.5 模板方法模式 (Template Method)

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

  • 前端场景: UI 组件的生命周期钩子 (created, mounted), 骨架屏加载流程。

3.6 职责链模式 (Chain of Responsibility)

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。

  • 前端场景: Node.js/Koa/Express 中间件, 作用域链, 事件冒泡。

3.7 命令模式 (Command)

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。

  • 前端场景: 富文本编辑器的撤销/重做 (Undo/Redo), 宏命令。

3.8 迭代器模式 (Iterator)

顺序访问聚合对象中的元素。

  • 前端场景: for...of, Array.prototype.forEach, 生成器 (Generator)。

3.9 访问者模式 (Visitor)

表示一个作用于某对象结构中的各元素的操作。

  • 前端场景: Babel 插件 (遍历 AST 节点并修改), 深度优先遍历 DOM 树。

3.10 中介者模式 (Mediator)

用一个中介对象来封装一系列的对象交互。

  • 前端场景: 传统的 MVC Controller, 复杂的表单联动 (通过一个中心控制各输入框状态)。

3.11 备忘录模式 (Memento)

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。

  • 前端场景: Redux DevTools (Time Travel), 状态快照保存与恢复。

3.12 解释器模式 (Interpreter)

给定一个语言,定义它的文法的一种表示,并定义一个解释器。

  • 前端场景: 模板引擎 (Mustache, Vue template 编译), 正则表达式。

Power by VitePress