前端常见设计模式

109 阅读2分钟

在 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 中常结合语言特性(如高阶函数、闭包)灵活实现。