前端常用设计模式
设计模式是软件开发中解决特定问题的成熟方案。在前端开发中,合理使用设计模式可以提高代码的可维护性、可扩展性和复用性。虽然经典的 GoF 设计模式有 23 种,但在前端开发中,部分模式的使用频率远高于其他模式。以下是较为完整的列表。
1. 创建型模式 (Creational Patterns)
关注对象的创建过程,将对象的创建和使用分离。
1.1 单例模式 (Singleton)
保证一个类仅有一个实例,并提供一个全局访问点。
- 前端场景: Vuex/Redux Store, 全局 Modal/Toast, Axios 实例。
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 配置对象生成器。
// 链式调用构建
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 编译), 正则表达式。
