23种设计模式案例
一、创建型模式
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
总结
这些设计模式在前端开发中都有广泛的应用场景:
- 创建型模式主要用于对象的创建和管理,帮助解耦对象的创建和使用
- 结构型模式关注类和对象的组合,形成更大的结构
- 行为型模式专注于对象之间的通信和职责分配
在实际开发中,这些模式经常组合使用,而不是孤立存在。理解这些模式的核心思想和适用场景,可以帮助我们设计出更加灵活、可维护的前端架构。