引言
設計模式是前端工程化架構的基石,通過抽象核心場景解法提升代碼復用性與系統可維護性。本文精析 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,本質是策略模式(渲染位置決策)、代理模式(服務端-客戶端組件橋接)與組合模式的深度融合。掌握模式內核,方能設計出 高內聚、低耦合 的前端系統。