05 · 设计模式(前端视角)
设计模式不是 GOF 全书背诵,而是"你已经用过、只是没命名"的套路。本篇把前端最常见的模式翻译成日常代码:观察者、工厂、单例、策略、适配器、代理,讲清"什么时候用、什么时候别硬套"。
速览卡
| 项 | 内容 |
|---|---|
| 一句话定位 | 把前端天天在用的设计套路对号入座 |
| 核心内容 | 高频六模式的前端形态、状态管理里的模式 |
| 读完能回答 | Redux 用了哪些模式?什么时候不该用模式? |
| 相关板块 | E04 数据结构与算法 | A19 前端设计模式 |
一、模式是什么,不是什么
| 是 | 不是 |
|---|---|
| 沟通词汇("这里用观察者") | 银弹 |
| 对重复问题的命名方案 | 写码模板 |
| 有代价的取舍 | 越多越好 |
判断框架:先有"反复出现的具体问题",才谈模式;没有痛点的模式是过度设计。
二、六个前端高频模式
| 模式 | 一句话 | 前端例子 |
|---|---|---|
| 观察者 | 数据变了通知一堆订阅者 | 状态管理、事件总线 |
| 工厂 | 一个函数按参数造不同对象 | 创建不同请求客户端 |
| 单例 | 全局只此一份 | 配置对象、连接池 |
| 策略 | 行为可替换 | 不同排序/校验器 |
| 适配器 | 把接口翻译成预期形状 | 封装第三方 SDK |
| 代理 | 拦截真实对象 | 请求拦截、防抖代理 |
三、状态管理里的模式
text
Redux/Zustand
├── 观察者:订阅 state 变化 → 触发渲染
├── 命令:dispatch(action) 描述"发生了什么"
├── 单例:store 全局唯一
└── 发布-订阅:组件不直接互相引用看懂这一条,前端框架的状态管理就不再是黑盒。
四、代理:前端最常见的隐形模式
ts
// 请求层做统一拦截(日志/鉴权/重试)
const api = new Proxy(client, {
get(target, prop) {
return async (...args) => {
console.log(`[api] ${prop}`, args);
return target[prop](...args);
};
},
});五、什么时候别用
| 信号 | 结论 |
|---|---|
| 只有一处用到 | 别抽抽象 |
| 为"将来可能"造接口 | 别,YAGNI |
| 用回调/函数就能解决 | 别造类 |
| 队友读不懂 | 模式要为沟通服务,不是表演 |
六、自检清单
- [ ] 能说出六个高频模式各自的前端例子
- [ ] 能指认状态管理里用了哪些模式
- [ ] 能区分"该用模式"和"过度设计"
- [ ] 能在代码里认出一个适配器 / 代理
七、常见误区
| 误区 | 事实 |
|---|---|
| "模式越多越专业" | 过度设计是负面信号 |
| "设计模式是后端的事" | 前端天天在用,只是没命名 |
| "背出 23 个模式就行" | 会用、会取舍才值钱 |
| "单例一定好" | 它隐藏依赖,测试更麻烦 |
八、动手练习
练习 A:给代码命名
找出你项目里的三个函数/模块,判断它们各属于哪个模式,写进注释。
练习 B:实现一个观察者
用几十行实现最小发布-订阅,再对比它和状态管理库的差距。
练习 C:重构一个 if-else
把一个多分支校验改成策略表(对象映射函数),体会"策略模式"的收益与代价。
相关文档
本区
- 04 · 数据结构与算法(前端视角) —— 模式背后的结构
前端区
- 19 · 前端设计模式 —— 更系统的前端模式清单
- 07 · 状态管理演进与选型 —— 状态管理的模式底细
- 14 · 组件 API 设计与设计系统 —— 组件层的模式应用