在 JavaScript 中,设计模式是解决常见问题的经典方案。以下是 10 个最常用的设计模式,结合代码示例和实际应用场景:
一、创建型模式
1. 工厂模式 (Factory Pattern)
通过工厂函数创建对象,隐藏实例化逻辑。
class Car {
constructor(type) { this.type = type; }
}
function createCar(type) {
return new Car(type);
}
const sedan = createCar('sedan'); // 无需直接 new Car()
场景:动态创建对象(如 UI 组件库)。
2. 单例模式 (Singleton Pattern)
确保类只有一个实例。
class Logger {
constructor() {
if (!Logger.instance) {
Logger.instance = this;
}
return Logger.instance;
}
}
const logger1 = new Logger();
const logger2 = new Logger();
console.log(logger1 === logger2); // true
场景:全局状态管理(如 Redux Store)、日志工具。
3. 原型模式 (Prototype Pattern)
利用 JavaScript 的原型链实现对象复用。
const carPrototype = {
wheels: 4,
drive() { console.log('Driving...'); }
};
const myCar = Object.create(carPrototype);
myCar.color = 'red';
场景:性能优化(避免重复创建相似对象)。
二、结构型模式
4. 装饰器模式 (Decorator Pattern)
动态扩展对象功能(ES7 语法)。
function withAutopilot(car) {
return {
...car,
autopilot: true,
activateAutopilot() { console.log('Autopilot engaged'); }
};
}
const tesla = withAutopilot(new Car('Model S'));
tesla.activateAutopilot();
场景:增强第三方库、AOP 编程。
5. 代理模式 (Proxy Pattern)
通过代理对象控制对原对象的访问。
const user = { name: 'John', age: 30 };
const userProxy = new Proxy(user, {
get(target, prop) {
console.log(`Accessing ${prop}`);
return target[prop];
}
});
console.log(userProxy.age); // 输出日志后返回 30
场景:数据验证、缓存(如 Vue3 的响应式系统)。
6. 适配器模式 (Adapter Pattern)
转换接口以兼容不同系统。
// 旧接口
class OldAPI {
request() { return 'Legacy Data'; }
}
// 适配器
class Adapter {
constructor(oldAPI) {
this.oldAPI = oldAPI;
}
fetch() {
return this.oldAPI.request();
}
}
const adapter = new Adapter(new OldAPI());
adapter.fetch(); // 转换为新接口
场景:整合第三方库、重构旧代码。
三、行为型模式
7. 观察者模式 (Observer Pattern)
实现对象间的一对多依赖(事件驱动)。
class EventEmitter {
constructor() {
this.listeners = {};
}
on(event, cb) {
if (!this.listeners[event]) this.listeners[event] = [];
this.listeners[event].push(cb);
}
emit(event, data) {
(this.listeners[event] || []).forEach(cb => cb(data));
}
}
const emitter = new EventEmitter();
emitter.on('click', data => console.log(data));
emitter.emit('click', 'Clicked!');
场景:DOM 事件、React/Vue 组件通信。
8. 策略模式 (Strategy Pattern)
动态选择算法策略。
const strategies = {
add: (a, b) => a + b,
subtract: (a, b) => a - b
};
function calculate(strategy, a, b) {
return strategies[strategy](a, b);
}
calculate('add', 5, 3); // 8
场景:表单验证规则、支付方式切换。
9. 状态模式 (State Pattern)
通过状态对象改变行为。
class TrafficLight {
constructor() {
this.states = [new RedState(), new GreenState()];
this.current = this.states[0];
}
change() {
this.current = this.states[1];
}
signal() {
return this.current.show();
}
}
class RedState {
show() { return 'STOP'; }
}
场景:游戏角色状态、订单流程。
10. 中间件模式 (Middleware Pattern)
串联处理请求(常见于 Express/Koa)。
function pipeline(middlewares) {
return (context) => {
function run(index) {
const middleware = middlewares[index];
if (middleware) {
return middleware(context, () => run(index + 1));
}
}
return run(0);
}
}
// 使用
const stack = [
(ctx, next) => { console.log('1'); next(); },
(ctx, next) => { console.log('2'); }
];
pipeline(stack)({}); // 输出 1, 2
场景:HTTP 请求处理、数据加工流水线。
总结
| 模式 | 典型场景 |
|---|---|
| 工厂模式 | 动态创建对象 |
| 单例模式 | 全局状态管理 |
| 代理模式 | 数据缓存/验证 |
| 观察者模式 | 事件驱动系统 |
| 中间件模式 | 请求处理管道 |
这些模式并非必须严格遵守,JavaScript 中常结合语言特性(如高阶函数、闭包)灵活实现。