前端常用设计模式全解析:从原理到实战
其实这个可以当计算机基础(八股)考 也可以当写题(发布订阅)也可以结合项目聊(显得有思考)其实熟悉设计模式应该对你阅读一些常见库的源码有帮助
本文将系统性介绍前端开发中常用的设计模式,结合实际应用场景,帮助你掌握从抽象思想到实战落地的能力。
一、单例模式(Singleton Pattern)
模式概述
保证一个类仅有一个实例,并提供一个全局访问点。
典型场景
- Vuex/Redux 的 store 实例
- 全局弹窗(Message、Modal)组件
- 配置管理(如全局主题、国际化配置)
示例
const GlobalConfig = (function () { let instance; function createInstance() { return { theme: 'dark' }; } return { getInstance() { if (!instance) { instance = createInstance(); } return instance; } }; })();
二、观察者模式(Observer Pattern)
模式概述
对象间建立一种一对多的依赖关系,当一个对象状态改变时,所有依赖它的对象都会收到通知。
典型场景
- Vue 的响应式系统(Object.defineProperty / Proxy)
- 发布订阅(event bus)
- WebSocket 消息通知、数据流更新
示例
class EventBus { constructor() { this.events = {}; } on(event, handler) { (this.events[event] ||= []).push(handler); } emit(event, ...args) { (this.events[event] || []).forEach(fn => fn(...args)); } } const bus = new EventBus(); bus.on('data', msg => console.log('Got:', msg)); bus.emit('data', 'Hello');
三、工厂模式(Factory Pattern)
模式概述
定义一个用于创建对象的接口,让子类决定实例化哪一个类。
典型场景
- 创建不同类型的 UI 控件(按钮、输入框)
- 动态组件渲染(按条件生成组件)
- Axios 请求拦截器工厂
示例
function createComponent(type) { switch (type) { case 'button': return document.createElement('button'); case 'input': return document.createElement('input'); default: return document.createElement('div'); } }
四、策略模式(Strategy Pattern)
模式概述
定义一系列算法,把它们一个个封装起来,并且使它们可以互换。
典型场景
- 表单校验策略(required, email, minLength)
- 动画控制策略(不同 easing 函数)
- 路由守卫策略(不同角色处理逻辑)
示例
const validators = { required: val => !!val, email: val => /\S+@\S+\.\S+/.test(val), }; function validate(type, val) { return validators[type](val); } console.log(validate('email', **********'));
五、装饰器模式(Decorator Pattern)
模式概述
在不改变对象自身的基础上,动态扩展功能。
典型场景
- 高阶组件(React HOC)
- Vue 的指令(v-loading)
- 日志打印、权限控制等切面逻辑注入
示例(React HOC)
function withLog(WrappedComponent) { return function (props) { console.log('Props:', props); return <WrappedComponent {...props} />; }; }
六、适配器模式(Adapter Pattern)
模式概述
将一个类的接口转换成客户端期望的另一个接口。
典型场景
- 老旧数据格式适配新组件
- API 返回值字段统一
- 第三方库接口包装
示例
function adaptUserData(raw) { return { name: raw.username, age: raw.user_age, }; }
七、代理模式(Proxy Pattern)
模式概述
为其他对象提供一种代理以控制对这个对象的访问
典型场景
- 图片懒加载
- 数据缓存(前端缓存代理)
- 统一接口鉴权与节流控制
示例(懒加载图片)
const lazyLoad = (function () { const img = new Image(); img.src = 'real.jpg'; return function (target) { target.src = 'loading.gif'; img.onload = () => { target.src = img.src; }; }; })();
八、命令模式(Command Pattern)
模式概述
将请求封装成对象,以便参数化不同请求、排队或记录日志。
典型场景
- 撤销/重做(如富文本编辑器)
- 按钮事件抽象
- 宏命令组合执行
九、组合模式(Composite Pattern)
模式概述
将对象组合成树形结构以表示“部分-整体”的层次结构。
典型场景
- React 组件树(组件可以嵌套组件)
- DOM 节点树
- 文件夹/菜单结构
十、职责链模式(Chain of Responsibility)
模式概述
为请求创建一个接收者对象的链,每个对象依次处理请求,直到完成处理。
典型场景
- Express 中间件机制
- Vue 生命周期钩子执行链
- 表单提交前多阶段校验
示例(中间件机制)
function compose(middlewares) { return function () { let index = 0; function next() { const fn = middlewares[index++]; if (fn) fn(next); } next(); }; } compose([ next => { console.log(1); next(); }, next => { console.log(2); next(); }, ])(); // 输出 1 2
总结
设计模式不是面试背诵题,而是实际开发中解决“代码复杂性、维护性、可扩展性”的经验总结。对于前端开发者而言:
- 在项目中合理引入设计模式,有助于团队协作和代码演化;
- 熟悉其背后的动机与实现逻辑,是迈向中高级工程师的重要一步;
- 模式不应滥用,只有遇到合适场景、识别出模式匹配的结构,才是成熟的工程判断。