一、什么是设计模式?
一套被反复验证、解决某类场景的最佳代码写法。
目的:
- 代码好维护
- 好扩展
- 少改旧代码
- 结构清晰
前端常用的就 10 种左右,记住这些足够面试+工作。
二、三大类(先记框架)
- 创建型:怎么 new / 怎么生成对象(单例、工厂、原型)
- 结构型:怎么组合类/对象(适配器、装饰器、代理、外观)
- 行为型:对象之间怎么通信、怎么控制流程(观察者、发布订阅、策略、迭代器、状态)
三、前端必学 10 大设计模式(重点)
1)单例模式(创建型)
核心:一个类只允许产生一个实例
- 全局唯一弹窗、全局状态管理、全局请求实例
- Vuex/Pinia、axios 实例、全局消息提示
js
class Singleton {
static instance = null
static getInstance() {
if (!this.instance) this.instance = new Singleton()
return this.instance
}
}
口诀:只生一个,全局共用
2)工厂模式(创建型)
核心:封装 new 过程,统一创建对象
- 批量创建相似节点
- 表单组件创建、不同类型弹窗
js
function createNode(type) {
if(type === 'div') return document.createElement('div')
if(type === 'p') return document.createElement('p')
}
口诀:不直接 new,交给工厂造
3)适配器模式(结构型)
核心:把不兼容接口转成兼容
- 后端返回数据结构不统一
- 老接口兼容新组件
js
function adapt(oldData) {
return { label: oldData.name, value: oldData.id }
}
口诀:接口不兼容,加个转换器
4)装饰器模式(结构型)
核心:不修改原函数,给它加功能
- 日志、埋点、权限校验、防抖节流
- ES Decorator、Vue 自定义装饰器
js
function log(fn) {
return (...args) => {
console.log('调用前')
const res = fn(...args)
console.log('调用后')
return res
}
}
口诀:不改本体,穿件衣服增强
5)代理模式(结构型)
核心:用代理对象控制原对象访问
- 图片懒加载、缓存、权限拦截
- ES6 Proxy、Vue3 响应式核心
js
const proxy = new Proxy(obj, {
get(target, key) { ... },
set(target, key, val) { ... }
})
口诀:不让你直接碰,我替你访问
6)外观模式(结构型)
核心:封装复杂逻辑,对外一个简单接口
- 封装工具库、封装 API 请求
js
function request(url, data) {
// 内部处理 token、loading、错误、拦截
return axios(...)
}
口诀:内部一团乱,对外一个门
7)观察者模式(行为型)
核心:一对一定时推送,目标变化通知观察者
- 组件监听数据变化
- 类似 Vue 的依赖收集
口诀:我变你知道,直接通知你
8)发布订阅模式(行为型)⭐ 最常用
核心:事件中心调度,发布 <-> 订阅 解耦
- eventBus、mitt、on/off/emit
- 跨组件通信
js
class EventBus {
list = {}
on(name, fn) {...}
emit(name, data) {...}
off(name, fn) {...}
}
口诀:你发事件,我监听,互不认识
面试必问:观察者 vs 发布订阅
- 观察者:目标和观察者互相认识
- 发布订阅:通过事件中心,完全解耦
9)策略模式(行为型)
核心:把多种算法/逻辑做成策略,按需切换
- 表单验证、不同支付方式、不同权限
js
const strategies = {
vip: ()=>{},
normal: ()=>{}
}
function useStrategy(type) {
return strategies[type]()
}
口诀:少写 if-else,用策略替换
10)状态模式(行为型)
核心:根据状态不同执行不同行为
- 订单状态(待支付/已支付/已取消)
- 流程审批、播放器状态
口诀:状态一变,行为自动变
四、一张表速记(面试直接背)
| 模式 | 一句话 | 前端场景 |
|---|---|---|
| 单例 | 全局唯一实例 | Pinia、axios实例 |
| 工厂 | 统一创建对象 | 批量生成组件 |
| 适配器 | 数据格式转换 | 接口数据适配 |
| 装饰器 | 增强不修改原函数 | 埋点、日志 |
| 代理 | 控制访问 | Vue3响应式 |
| 外观 | 封装复杂接口 | 统一request |
| 发布订阅 | 事件通信 | mitt、eventBus |
| 策略 | 替换if-else | 表单验证 |
| 状态 | 状态切换行为 | 订单/播放器 |
五、最简单总结
- 想全局唯一 → 单例
- 想创建一批对象 → 工厂
- 想加功能不改原代码 → 装饰器
- 想监听通信 → 发布订阅
- 想少写if-else → 策略模式
- 想控制对象访问 → 代理
- 想兼容老接口 → 适配器