一、創建型模式
1. 單例模式 (Singleton Pattern)
應用場景: 全局狀態管理、全局配置、共享資源訪問
// 全局狀態管理器
class Store {constructor() {if (Store.instance) return Store.instance;this.state = {};Store.instance = this;}getState(key) { return this.state[key]; }setState(key, value) { this.state[key] = value; }
}// 使用示例
const store1 = new Store();
const store2 = new Store();
console.log(store1 === store2); // truestore1.setState('user', { name: 'John' });
console.log(store2.getState('user')); // { name: 'John' }
2. 工廠方法模式 (Factory Pattern)
應用場景: 創建不同類型的UI組件、數據請求對象
class Button {render() { /* 基礎按鈕渲染 */ }
}class PrimaryButton extends Button {render() { /* 主要按鈕渲染 */ }
}class DangerButton extends Button {render() { /* 危險按鈕渲染 */ }
}class ButtonFactory {static createButton(type) {switch(type) {case 'primary': return new PrimaryButton();case 'danger': return new DangerButton();default: return new Button();}}
}// 使用示例
const primaryBtn = ButtonFactory.createButton('primary');
primaryBtn.render();
3. 抽象工廠模式 (Abstract Factory Pattern)
應用場景: 創建主題相關的UI組件族
// 抽象工廠
class ThemeFactory {createButton() {}createInput() {}
}// 具體工廠 - 亮色主題
class LightThemeFactory extends ThemeFactory {createButton() { return new LightButton(); }createInput() { return new LightInput(); }
}// 具體工廠 - 暗色主題
class DarkThemeFactory extends ThemeFactory {createButton() { return new DarkButton(); }createInput() { return new DarkInput(); }
}// 使用示例
const theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? new DarkThemeFactory() : new LightThemeFactory();const button = theme.createButton();
const input = theme.createInput();
4. 建造者模式 (Builder Pattern)
應用場景: 構建復雜表單、配置復雜對象
class FormBuilder {constructor() {this.form = {fields: [],validations: [],onSubmit: null};}addField(type, name, placeholder = '') {this.form.fields.push({ type, name, placeholder });return this;}addValidation(fieldName, validator) {this.form.validations.push({ fieldName, validator });return this;}setSubmitHandler(handler) {this.form.onSubmit = handler;return this;}build() {return this.form;}
}// 使用示例
const loginForm = new FormBuilder().addField('text', 'username', '請輸入用戶名').addField('password', 'password', '請輸入密碼').addValidation('username', value => value.length >= 3).setSubmitHandler(data => console.log('提交數據:', data)).build();
5. 原型模式 (Prototype Pattern)
應用場景: 組件克隆、對象復制
// 基礎組件原型
const baseComponent = {render() { console.log('渲染組件'); },clone() { return Object.create(this); }
};// 使用示例
const component1 = baseComponent.clone();
const component2 = baseComponent.clone();component1.customMethod = function() { console.log('自定義方法'); };component1.render(); // 渲染組件
component2.render(); // 渲染組件
component1.customMethod(); // 自定義方法
二、結構型模式
6. 適配器模式 (Adapter Pattern)
應用場景: 統一不同數據源的接口格式
// 老版本API
class OldAPI {request() { return { data: { items: [] } }; }
}// 新版本API適配器
class APIAdapter {constructor(oldAPI) {this.oldAPI = oldAPI;}fetch() {const result = this.oldAPI.request();return { success: true, data: result.data.items };}
}// 使用示例
const oldAPI = new OldAPI();
const adapter = new APIAdapter(oldAPI);
const data = adapter.fetch(); // { success: true, data: [] }
7. 裝飾器模式 (Decorator Pattern)
應用場景: 增強組件功能、添加日志、權限控制
// 基礎組件
class Component {render() { console.log('渲染組件'); }
}// 裝飾器 - 添加日志
function withLogging(WrappedComponent) {return class extends WrappedComponent {render() {console.log('開始渲染');const result = super.render();console.log('渲染完成');return result;}};
}// 使用示例
const EnhancedComponent = withLogging(Component);
const component = new EnhancedComponent();
component.render();
8. 外觀模式 (Facade Pattern)
應用場景: 簡化復雜庫的API調用
// 復雜的三方圖表庫
class ComplexChartLib {init(config) { /* 復雜初始化 */ }setData(data) { /* 復雜數據設置 */ }render() { /* 復雜渲染邏輯 */ }destroy() { /* 復雜銷毀邏輯 */ }
}// 簡化外觀
class ChartFacade {constructor(container) {this.chart = new ComplexChartLib();this.container = container;}show(data, options = {}) {this.chart.init({ container: this.container, ...options });this.chart.setData(data);this.chart.render();}update(data) {this.chart.setData(data);}destroy() {this.chart.destroy();}
}// 使用示例
const chart = new ChartFacade('#chart-container');
chart.show([{ value: 10 }, { value: 20 }]);
9. 橋接模式 (Bridge Pattern)
應用場景: 分離UI組件樣式與行為
// 實現部分 - 渲染器
class Renderer {renderCircle(radius) {}
}class SVGRenderer extends Renderer {renderCircle(radius) {console.log(`繪制SVG圓形,半徑: ${radius}`);}
}class CanvasRenderer extends Renderer {renderCircle(radius) {console.log(`繪制Canvas圓形,半徑: ${radius}`);}
}// 抽象部分 - 形狀
class Shape {constructor(renderer) {this.renderer = renderer;}draw() {}
}class Circle extends Shape {constructor(renderer, radius) {super(renderer);this.radius = radius;}draw() {this.renderer.renderCircle(this.radius);}
}// 使用示例
const svgRenderer = new SVGRenderer();
const canvasRenderer = new CanvasRenderer();const circle1 = new Circle(svgRenderer, 5);
circle1.draw(); // 繪制SVG圓形,半徑: 5const circle2 = new Circle(canvasRenderer, 10);
circle2.draw(); // 繪制Canvas圓形,半徑: 10
10. 組合模式 (Composite Pattern)
應用場景: 構建樹形結構的UI組件
// 組件接口
class UIComponent {render() {}add(component) {}remove(component) {}
}// 葉子組件
class Button extends UIComponent {render() { console.log('渲染按鈕'); }add() { throw new Error('葉子組件不能添加子組件'); }remove() { throw new Error('葉子組件不能移除子組件'); }
}// 復合組件
class Panel extends UIComponent {constructor() {super();this.children = [];}add(component) { this.children.push(component); }remove(component) { this.children = this.children.filter(c => c !== component);}render() {console.log('開始渲染面板');this.children.forEach(child => child.render());console.log('完成渲染面板');}
}// 使用示例
const panel = new Panel();
panel.add(new Button());
panel.add(new Button());const subPanel = new Panel();
subPanel.add(new Button());
panel.add(subPanel);panel.render();
11. 享元模式 (Flyweight Pattern)
應用場景: 共享圖標、樣式等細粒度對象
class IconFactory {constructor() {this.icons = {};}getIcon(type) {if (!this.icons[type]) {this.icons[type] = this.createIcon(type);}return this.icons[type];}createIcon(type) {// 模擬創建圖標的昂貴操作console.log(`創建 ${type} 圖標`);return { render: () => console.log(`渲染 ${type} 圖標`) };}
}// 使用示例
const factory = new IconFactory();
const icon1 = factory.getIcon('delete');
const icon2 = factory.getIcon('delete'); // 不會重新創建icon1.render(); // 渲染 delete 圖標
icon2.render(); // 渲染 delete 圖標
12. 代理模式 (Proxy Pattern)
應用場景: 權限控制、緩存、懶加載
// 真實對象
class ImageLoader {load(url) {console.log(`加載圖片: ${url}`);return `圖片數據: ${url}`;}
}// 代理 - 添加緩存
class ImageLoaderProxy {constructor() {this.loader = new ImageLoader();this.cache = new Map();}load(url) {if (this.cache.has(url)) {console.log(`從緩存獲取圖片: ${url}`);return this.cache.get(url);}const data = this.loader.load(url);this.cache.set(url, data);return data;}
}// 使用示例
const proxy = new ImageLoaderProxy();
proxy.load('image1.jpg'); // 加載圖片: image1.jpg
proxy.load('image1.jpg'); // 從緩存獲取圖片: image1.jpg
三、行為型模式
13. 策略模式 (Strategy Pattern)
應用場景: 不同的數據驗證策略、排序策略
// 策略類
const validationStrategies = {required: (value) => !!value,email: (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value),minLength: (value, length) => value.length >= length
};// 上下文
class Validator {constructor() {this.strategies = [];}addStrategy(strategy, value, ...args) {this.strategies.push({ strategy, value, args });}validate() {return this.strategies.every(({ strategy, value, args }) => validationStrategies[strategy](value, ...args));}
}// 使用示例
const validator = new Validator();
validator.addStrategy('required', 'input value');
validator.addStrategy('minLength', 'hello', 3);console.log(validator.validate()); // true
14. 模板方法模式 (Template Method Pattern)
應用場景: 定義通用請求流程
// 抽象類
class DataFetcher {// 模板方法async fetchData() {this.showLoading();try {const data = await this.requestData();this.processData(data);this.hideLoading();return data;} catch (error) {this.handleError(error);this.hideLoading();throw error;}}// 抽象方法async requestData() { throw new Error('必須實現 requestData'); }// 具體方法showLoading() { console.log('顯示加載中...'); }hideLoading() { console.log('隱藏加載中'); }processData(data) { console.log('處理數據:', data); }handleError(error) { console.error('處理錯誤:', error.message); }
}// 具體實現
class UserDataFetcher extends DataFetcher {async requestData() {// 模擬API請求return await Promise.resolve([{ id: 1, name: 'John' }]);}
}// 使用示例
const fetcher = new UserDataFetcher();
fetcher.fetchData();
15. 觀察者模式 (Observer Pattern)
應用場景: 事件系統、數據響應式更新
class Observable {constructor() {this.observers = [];}subscribe(observer) {this.observers.push(observer);}unsubscribe(observer) {this.observers = this.observers.filter(obs => obs !== observer);}notify(data) {this.observers.forEach(observer => observer.update(data));}
}class Observer {update(data) {console.log('收到數據:', data);}
}// 使用示例
const observable = new Observable();
const observer1 = new Observer();
const observer2 = new Observer();observable.subscribe(observer1);
observable.subscribe(observer2);observable.notify('新數據'); // 兩個觀察者都會收到通知
16. 迭代器模式 (Iterator Pattern)
應用場景: 遍歷集合、自定義數據結構遍歷
class Collection {constructor() {this.items = [];}add(item) { this.items.push(item); }[Symbol.iterator]() {let index = 0;const items = this.items;return {next() {return index < items.length ? { value: items[index++], done: false }: { done: true };}};}
}// 使用示例
const collection = new Collection();
collection.add('item1');
collection.add('item2');
collection.add('item3');for (const item of collection) {console.log(item); // item1, item2, item3
}
17. 職責鏈模式 (Chain of Responsibility Pattern)
應用場景: 中間件管道、請求處理鏈
class Handler {constructor() {this.nextHandler = null;}setNext(handler) {this.nextHandler = handler;return handler;}handle(request) {if (this.nextHandler) {return this.nextHandler.handle(request);}return null;}
}class AuthHandler extends Handler {handle(request) {if (!request.user) {throw new Error('未認證');}console.log('認證通過');return super.handle(request);}
}class ValidationHandler extends Handler {handle(request) {if (!request.data) {throw new Error('數據無效');}console.log('驗證通過');return super.handle(request);}
}// 使用示例
const authHandler = new AuthHandler();
const validationHandler = new ValidationHandler();authHandler.setNext(validationHandler);try {authHandler.handle({ user: { id: 1 }, data: 'some data' });
} catch (error) {console.error(error.message);
}
18. 命令模式 (Command Pattern)
應用場景: 實現撤銷/重做功能
// 命令接口
class Command {execute() {}undo() {}
}// 具體命令
class AddItemCommand extends Command {constructor(list, item) {super();this.list = list;this.item = item;}execute() {this.list.add(this.item);}undo() {this.list.remove(this.item);}
}// 接收者
class ShoppingList {constructor() {this.items = [];}add(item) {this.items.push(item);console.log(`添加: ${item}`);}remove(item) {this.items = this.items.filter(i => i !== item);console.log(`移除: ${item}`);}
}// 調用者
class CommandManager {constructor() {this.history = [];this.redoStack = [];}execute(command) {command.execute();this.history.push(command);this.redoStack = [];}undo() {const command = this.history.pop();if (command) {command.undo();this.redoStack.push(command);}}redo() {const command = this.redoStack.pop();if (command) {command.execute();this.history.push(command);}}
}// 使用示例
const list = new ShoppingList();
const manager = new CommandManager();manager.execute(new AddItemCommand(list, '牛奶'));
manager.execute(new AddItemCommand(list, '面包'));
manager.undo(); // 移除: 面包
manager.redo(); // 添加: 面包
19. 備忘錄模式 (Memento Pattern)
應用場景: 保存和恢復表單狀態
class EditorMemento {constructor(content) {this.content = content;this.timestamp = Date.now();}
}class Editor {constructor() {this.content = '';this.history = [];}type(text) {this.content += text;}save() {const memento = new EditorMemento(this.content);this.history.push(memento);return memento;}restore(memento) {this.content = memento.content;}getHistory() {return this.history.map(m => ({content: m.content,timestamp: new Date(m.timestamp).toLocaleTimeString()}));}
}// 使用示例
const editor = new Editor();
editor.type('Hello');
const save1 = editor.save();editor.type(' World');
const save2 = editor.save();console.log(editor.content); // Hello Worldeditor.restore(save1);
console.log(editor.content); // Helloconsole.log(editor.getHistory());
20. 狀態模式 (State Pattern)
應用場景: 復雜的狀態管理
class TrafficLight {constructor() {this.states = {red: new RedState(this),yellow: new YellowState(this),green: new GreenState(this)};this.currentState = this.states.red;}changeState(state) {this.currentState = this.states[state];}request() {this.currentState.handle();}
}class LightState {constructor(light) {this.light = light;}handle() { throw new Error('必須實現handle方法'); }
}class RedState extends LightState {handle() {console.log('紅燈 - 停止');setTimeout(() => this.light.changeState('green'), 3000);}
}class GreenState extends LightState {handle() {console.log('綠燈 - 通行');setTimeout(() => this.light.changeState('yellow'), 3000);}
}class YellowState extends LightState {handle() {console.log('黃燈 - 準備');setTimeout(() => this.light.changeState('red'), 1000);}
}// 使用示例
const trafficLight = new TrafficLight();
trafficLight.request(); // 紅燈
setTimeout(() => trafficLight.request(), 3000); // 綠燈
21. 訪問者模式 (Visitor Pattern)
應用場景: 對DOM樹進行操作
// 元素接口
class DOMElement {accept(visitor) { throw new Error('必須實現accept方法'); }
}// 具體元素
class DivElement extends DOMElement {accept(visitor) {visitor.visitDiv(this);}
}class SpanElement extends DOMElement {accept(visitor) {visitor.visitSpan(this);}
}// 訪問者接口
class Visitor {visitDiv(element) {}visitSpan(element) {}
}// 具體訪問者
class RenderVisitor extends Visitor {visitDiv(element) {console.log('渲染div元素');}visitSpan(element) {console.log('渲染span元素');}
}class StyleVisitor extends Visitor {visitDiv(element) {console.log('為div添加樣式');}visitSpan(element) {console.log('為span添加樣式');}
}// 使用示例
const elements = [new DivElement(), new SpanElement()];
const renderVisitor = new RenderVisitor();
const styleVisitor = new StyleVisitor();elements.forEach(element => {element.accept(renderVisitor);element.accept(styleVisitor);
});
22. 中介者模式 (Mediator Pattern)
應用場景: 組件間通信
class Mediator {constructor() {this.components = {};}register(name, component) {this.components[name] = component;component.setMediator(this);}notify(sender, event, data) {if (event === 'buttonClick') {this.components.form.update(data);} else if (event === 'formSubmit') {this.components.list.addItem(data);}}
}class BaseComponent {setMediator(mediator) {this.mediator = mediator;}
}class Button extends BaseComponent {click() {this.mediator.notify(this, 'buttonClick', { action: 'click' });}
}class Form extends BaseComponent {update(data) {console.log('表單更新:', data);}submit(data) {this.mediator.notify(this, 'formSubmit', data);}
}class List extends BaseComponent {addItem(item) {console.log('列表添加項:', item);}
}// 使用示例
const mediator = new Mediator();
const button = new Button();
const form = new Form();
const list = new List();mediator.register('button', button);
mediator.register('form', form);
mediator.register('list', list);button.click(); // 表單更新: { action: 'click' }
form.submit({ name: '新項目' }); // 列表添加項: { name: '新項目' }
23. 解釋器模式 (Interpreter Pattern)
應用場景: 模板解析、查詢語言解析
// 上下文
class Context {constructor(input) {this.input = input;this.output = 0;}
}// 表達式接口
class Expression {interpret(context) { throw new Error('必須實現interpret方法'); }
}// 具體表達式
class NumberExpression extends Expression {interpret(context) {context.output = parseInt(context.input);}
}class AddExpression extends Expression {constructor(left, right) {super();this.left = left;this.right = right;}interpret(context) {this.left.interpret(context);const leftResult = context.output;this.right.interpret(context);const rightResult = context.output;context.output = leftResult + rightResult;}
}// 使用示例
const context = new Context('5 3');
const expression = new AddExpression(new NumberExpression(),new NumberExpression()
);expression.interpret(context);
console.log(context.output); // 8
總結
這些設計模式在前端開發中都有廣泛的應用場景:
- 創建型模式主要用于對象的創建和管理,幫助解耦對象的創建和使用
- 結構型模式關注類和對象的組合,形成更大的結構
- 行為型模式專注于對象之間的通信和職責分配
在實際開發中,這些模式經常組合使用,而不是孤立存在。理解這些模式的核心思想和適用場景,可以幫助我們設計出更加靈活、可維護的前端架構。