# 前端常见设计模式深度解析
一、设计模式概述
设计模式是解决特定问题的经验总结,前端开发中常用的设计模式可分为三大类:
- 创建型模式:处理对象创建机制(单例、工厂等)
- 结构型模式:处理对象组合(装饰器、适配器等)
- 行为型模式:处理对象间通信(观察者、策略等)
二、核心设计模式详解
1. 单例模式(Singleton)
现代实现方案
const Singleton = (() => {
let instance;
function createInstance() {
return {
data: [],
add(item) {
this.data.push(item);
},
get() {
return [...this.data];
}
};
}
return {
getInstance() {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
// 使用示例
const store1 = Singleton.getInstance();
const store2 = Singleton.getInstance();
console.log(store1 === store2); // true
#### 应用场景
- Redux/Vuex的store管理
- 全局缓存对象
- 浏览器全局对象(如window)
### 2. 观察者模式(Observer)
#### 增强版实现
```javascript
class EventBus {
constructor() {
this.events = new Map();
}
on(event, callback, once = false) {
if (!this.events.has(event)) {
this.events.set(event, new Set());
}
this.events.get(event).add({ callback, once });
}
once(event, callback) {
this.on(event, callback, true);
}
emit(event, ...args) {
if (!this.events.has(event)) return;
const handlers = this.events.get(event);
handlers.forEach(handler => {
handler.callback(...args);
if (handler.once) {
this.off(event, handler.callback);
}
});
}
off(event, callback) {
if (!this.events.has(event)) return;
const handlers = this.events.get(event);
for (let handler of handlers) {
if (handler.callback === callback) {
handlers.delete(handler);
break;
}
}
}
}
// 使用示例
const bus = new EventBus();
bus.on('login', user => console.log(`User ${user.name} logged in`));
bus.emit('login', { name: 'Alice' });
实际应用
- Vue的EventBus
- DOM事件系统
- WebSocket消息处理
3. 工厂模式(Factory)
现代变体
interface Product {
operation(): string;
}
class ConcreteProductA implements Product {
operation() {
return 'Product A';
}
}
class ConcreteProductB implements Product {
operation() {
return 'Product B';
}
}
class ProductFactory {
static createProduct(type: 'A' | 'B'): Product {
switch (type) {
case 'A': return new ConcreteProductA();
case 'B': return new ConcreteProductB();
default: throw new Error('Invalid product type');
}
}
}
// 使用示例
const product = ProductFactory.createProduct('A');
console.log(product.operation()); // "Product A"
应用场景
- UI组件库(Button、Modal等)
- 不同环境配置(开发/生产)
- API客户端(REST/GraphQL切换)
三、其他重要设计模式
1. 策略模式(Strategy)
const strategies = {
add: (a, b) => a + b,
subtract: (a, b) => a - b,
multiply: (a, b) => a * b
};
class Calculator {
execute(strategy, a, b) {
return strategies[strategy]?.(a, b) ?? NaN;
}
}
// 使用示例
const calc = new Calculator();
console.log(calc.execute('add', 5, 3)); // 8
2. 装饰器模式(Decorator)
function withLogging(fn) {
return function(...args) {
console.log(`Calling ${fn.name} with`, args);
const result = fn.apply(this, args);
console.log(`Result:`, result);
return result;
};
}
// 使用示例
const add = withLogging((a, b) => a + b);
add(2, 3);
// 输出:
// Calling add with [2, 3]
// Result: 5
3. 代理模式(Proxy)
const apiProxy = new Proxy({}, {
get(target, endpoint) {
return async (params) => {
console.log(`Calling API: /${endpoint}`);
const res = await fetch(`https://api.example.com/${endpoint}`, {
method: 'POST',
body: JSON.stringify(params)
});
return res.json();
};
}
});
// 使用示例
const data = await apiProxy.users({ page: 1 });
四、设计模式在前端框架中的应用
设计模式 | React应用场景 | Vue应用场景 |
---|---|---|
观察者模式 | Context API | EventBus |
策略模式 | Hooks自定义逻辑 | 组件方法 |
装饰器模式 | HOC高阶组件 | 装饰器语法 |
代理模式 | ForwardRef | 计算属性 |
工厂模式 | createElement | 组件工厂 |
五、设计模式选择指南
何时使用单例模式:
- 需要全局唯一状态时
- 频繁访问的共享资源
- 避免重复初始化开销
何时使用观察者模式:
- 组件间松耦合通信
- 实时数据更新场景
- 跨层级组件交互
何时使用工厂模式:
- 创建过程复杂时
- 需要根据不同条件创建不同实例
- 需要隐藏创建细节
六、性能与注意事项
单例模式:
- 注意内存泄漏问题
- 考虑线程安全(在Web Worker场景)
观察者模式:
- 及时取消订阅
- 避免过度通知导致的性能问题
工厂模式:
- 不要过度设计简单对象创建
- 考虑与依赖注入结合使用
七、现代JavaScript中的新模式
- 组合模式(Composition):
const canFly = {
fly() {
console.log('Flying!');
}
};
const canSwim = {
swim() {
console.log('Swimming!');
}
};
function createFlyingFish() {
return Object.assign({}, canFly, canSwim);
}
- 模块模式(Module):
// ES Modules
export const api = {
get() { /* ... */ },
post() { /* ... */ }
};
// 或使用IIFE
const counter = (() => {
let count = 0;
return {
increment() { count++ },
get() { return count }
};
})();
掌握这些设计模式能显著提升代码质量,建议在实际项目中:
- 从简单模式开始应用
- 逐步尝试复杂模式组合
- 根据项目规模选择适当模式
- 避免过度设计简单场景