引言
设计模式是前端工程化架构的基石,通过抽象核心场景解法提升代码复用性与系统可维护性。本文精析 7 个核心模式,结合原生 JavaScript 与框架实践,揭示模式在现代前端架构中的底层映射与应用。
1. 观察者模式(Observer)
核心思想:状态变更自动通知依赖对象,实现发布-订阅解耦机制。
技术演进:从原生事件系统到响应式框架状态管理。
// 原生实现(明确订阅-通知生命周期)
class Observable {constructor() { this.observers = []; }subscribe(fn) { this.observers.push(fn); } // 显式订阅unsubscribe(fn) { /* 移除逻辑 */ } // 防止内存泄漏notify(data) { // 广播状态变更this.observers.forEach(observer => observer(data));}
}// 框架映射说明:
// - Vue reactive():基于 Proxy 实现细粒度依赖追踪
// - React useState():状态调度机制(非传统观察者),依赖 Fiber 架构批量更新
关键区分:原生观察者需显式管理订阅关系,而框架通过虚拟 DOM/响应式代理自动处理依赖。
2. 策略模式(Strategy)
核心思想:封装可互换算法族,运行时动态切换策略。
扩展场景:动态表单校验规则、多端渲染策略适配(Web/Mobile)。
// 多策略组合验证(支持异步)
const validationStrategies = {email: async (value) => { /* API 验证 */ },password: (value) => /[A-Z]/.test(value) // 包含大写字母
};class Validator {constructor(strategies) {this.strategies = strategies;this.errors = [];}async validate(key, value) {const result = await this.strategies[key](value);if (!result) this.errors.push(`${key}验证失败`);}
}
工业实践:Webpack 的 loader 链本质是策略管道,Vite 插件系统采用策略组合扩展编译行为。
3. 装饰器模式(Decorator)
核心思想:通过包装器增强功能,遵循开放封闭原则。
技术深化:AOP(面向切面编程)实现日志/性能埋点。
// TypeScript 方法装饰器(性能分析切面)
function logPerf(_: any, name: string, descriptor: PropertyDescriptor) {const original = descriptor.value;descriptor.value = function(...args) {const start = performance.now();const result = original.apply(this, args);console.log(`${name}执行耗时: ${performance.now() - start}ms`);return result;};
}class API {@logPerffetchData() { /* 网络请求 */ }
}
框架约束:React HOC 需遵守 displayName 规范,避免 DevTools 调试混淆。
4. 单例模式(Singleton)
核心思想:确保类唯一实例,全局共享状态/服务。
前端场景:全局状态管理、浏览器存储代理、WebSocket 连接池。
class AuthService { // 单例身份验证服务static instance;static getInstance() {if (!AuthService.instance) {AuthService.instance = new AuthService();}return AuthService.instance;}constructor() {this.token = localStorage.getItem('token');}login(token) { this.token = token;// 广播登录事件(结合观察者)}
}// 全应用统一访问点
const auth = AuthService.getInstance();
风险提示:单例模块化需考虑服务注销机制,避免 SPA 路由切换后状态残留。
5. 命令模式(Command)
核心思想:将操作封装为对象,支持撤销/重做与事务管理。
前端场景:操作历史栈、批量任务调度、UI 动作解耦。
// 可撤销的 Canvas 绘图命令
class DrawCommand {constructor(canvas, params) {this.canvas = canvas;this.params = params;this.prevState = canvas.getState(); // 保存前一状态}execute() {this.canvas.draw(this.params);}undo() {this.canvas.restore(this.prevState); // 恢复历史状态}
}// 命令管理器(支持事务)
class CommandManager {history = [];invoke(command) {command.execute();this.history.push(command);}undo() {const cmd = this.history.pop();cmd?.undo();}
}
应用实例:富文本编辑器操作历史、Redux 的 Action 命令化分发。
6. 代理模式(Proxy)
核心思想:中介对象控制访问,实现缓存/验证/懒加载。
性能优化:API 请求智能缓存代理。
const apiCache = new Map();const apiProxy = new Proxy(fetch, { // 拦截 fetchasync apply(target, _, args) {const [url] = args;if (apiCache.has(url)) return apiCache.get(url); // 返回缓存const res = await target(...args); // 执行真实请求apiCache.set(url, res);return res;}
});// 使用代理后的 fetch
apiProxy('/data').then(...);
陷阱规避:Proxy 嵌套对象需递归代理,避免部分属性未拦截。
7. 组合模式(Composite)
核心思想:统一处理树状结构,抽象部分-整体关系。
现代演进:微前端架构中的应用模块树。
// 插件系统组合(支持嵌套注册)
const PluginSystem = ({ children }) => {useEffect(() => {// 递归初始化所有子插件React.Children.forEach(children, plugin => plugin.init?.());}, []);return <>{children}</>;
};<PluginSystem><AnalyticsPlugin /><PluginSystem> {/* 嵌套组合 */}<SecurityPlugin /></PluginSystem>
</PluginSystem>
设计模式的应用
前端框架演进史本质是设计模式的融合实践。解耦艺术通过观察者模式将视图层与数据流分离(如 Vue 的响应式系统),而控制反转在工厂模式中体现为组件创建权移交框架(React 的 ReactDOM.createRoot)。单例模式实现全局状态共享(Redux store),却需警惕违反迪米特法则引发的隐式耦合。
在复杂交互场景,命令模式与策略模式的协同构成可撤销操作流水线:
-
用户动作封装为命令对象(Command)
-
命令管理器按策略模式选择执行/存储方案
-
代理模式拦截命令执行,注入性能监控
当代架构趋势如 React Server Components,本质是策略模式(渲染位置决策)、代理模式(服务端-客户端组件桥接)与组合模式的深度融合。掌握模式内核,方能设计出 高内聚、低耦合 的前端系统。