《JavaScript 设计模式全解析:核心分类 + 代码实战,告别“面条式代码”》

199 阅读3分钟

一、设计模式的分类

根据 《设计模式:可复用面向对象软件的基础》(GoF),设计模式分为三大类:

分类核心思想常见模式
创建型解决对象创建的问题,提供灵活的创建机制。工厂模式、单例模式、原型模式、建造者模式
结构型处理对象和类的组合,优化代码结构。适配器模式、装饰器模式、代理模式、组合模式
行为型管理对象间的通信和职责分配,提升协作效率。观察者模式、策略模式、命令模式、迭代器模式、状态模式

二、创建型模式(Creational Patterns)

1. 工厂模式(Factory Pattern)

  • 定义:通过一个工厂函数创建对象,隐藏具体实现细节。
  • 用途:解耦对象的创建和使用。
  • 代码示例
    class Car {
      constructor(name) { this.name = name; }
    }
    
    class Bike {
      constructor(name) { this.name = name; }
    }
    
    function VehicleFactory(type, name) {
      switch (type) {
        case 'car': return new Car(name);
        case 'bike': return new Bike(name);
        default: throw new Error('Unknown type');
      }
    }
    
    const car = VehicleFactory('car', 'Tesla');
    const bike = VehicleFactory('bike', 'Honda');
    

2. 单例模式(Singleton Pattern)

  • 定义:确保一个类只有一个实例,并提供全局访问点。
  • 用途:管理全局状态(如配置、日志)。
  • 代码示例
    class Logger {
      constructor() {
        if (!Logger.instance) {
          this.logs = [];
          Logger.instance = this;
        }
        return Logger.instance;
      }
    
      log(message) {
        this.logs.push(message);
        console.log(message);
      }
    }
    
    const logger1 = new Logger();
    const logger2 = new Logger();
    console.log(logger1 === logger2); // true
    

三、结构型模式(Structural Patterns)

1. 适配器模式(Adapter Pattern)

  • 定义:将一个类的接口转换成客户端期望的另一个接口。
  • 用途:兼容新旧接口。
  • 代码示例
    // 旧接口:返回 XML 数据
    class OldApi {
      getData() {
        return '<data>Hello</data>';
      }
    }
    
    // 适配器:将 XML 转为 JSON
    class ApiAdapter {
      constructor(oldApi) {
        this.oldApi = oldApi;
      }
    
      getData() {
        const xml = this.oldApi.getData();
        return { data: xml.replace(/<data>|<\/data>/g, '') };
      }
    }
    
    const adapter = new ApiAdapter(new OldApi());
    console.log(adapter.getData()); // { data: 'Hello' }
    

2. 装饰器模式(Decorator Pattern)

  • 定义:动态地为对象添加功能。
  • 用途:扩展对象的行为,避免继承的复杂性。(React中,高阶组件(HOC))
  • 代码示例
    class Coffee {
      cost() { return 5; }
    }
    
    // 装饰器:添加牛奶
    function withMilk(coffee) {
      const cost = coffee.cost();
      coffee.cost = () => cost + 2;
      return coffee;
    }
    
    const coffee = new Coffee();
    const milkCoffee = withMilk(coffee);
    console.log(milkCoffee.cost()); // 7
    

四、行为型模式(Behavioral Patterns)

1. 观察者模式(Observer Pattern)

  • 定义:定义对象间的一对多依赖关系,当一个对象状态改变时,自动通知所有依赖者。
  • 用途:事件处理、数据绑定。
  • 代码示例
    class Subject {
      constructor() {
        this.observers = [];
      }
    
      subscribe(observer) {
        this.observers.push(observer);
      }
    
      notify(data) {
        this.observers.forEach(observer => observer.update(data));
      }
    }
    
    class Observer {
      update(data) {
        console.log('Received data:', data);
      }
    }
    
    const subject = new Subject();
    const observer = new Observer();
    subject.subscribe(observer);
    subject.notify('Hello!'); // Received data: Hello!
    

2. 策略模式(Strategy Pattern)

  • 定义:定义一系列算法,并使其可以相互替换。
  • 用途:动态切换算法逻辑(如表单验证)。
  • 代码示例
    const strategies = {
      add: (a, b) => a + b,
      subtract: (a, b) => a - b,
    };
    
    class Calculator {
      constructor(strategy) {
        this.strategy = strategy;
      }
    
      execute(a, b) {
        return this.strategy(a, b);
      }
    }
    
    const addCalculator = new Calculator(strategies.add);
    console.log(addCalculator.execute(5, 3)); // 8
    

五、其他常用模式

模式用途示例场景
代理模式控制对对象的访问(如缓存、权限校验)。使用 Proxy 拦截对象操作。
迭代器模式提供遍历集合的统一接口。自定义可迭代对象(如树结构遍历)。
状态模式根据状态改变对象的行为。订单状态(待付款、已发货、已完成)。

总结

  • 创建型模式:解决对象创建问题(如工厂、单例)。
  • 结构型模式:优化对象组合(如适配器、装饰器)。
  • 行为型模式:管理对象协作(如观察者、策略)。

根据具体需求选择合适的设计模式,可以大幅提升代码的可维护性和扩展性! 🚀