跳转到内容

JavaScript面向对象设计模式

来自代码酷


JavaScript面向对象设计模式是使用面向对象编程(OOP)原则解决常见软件设计问题的可复用解决方案。设计模式提供了一种结构化的方式来处理代码组织、对象交互和系统架构,使代码更易于维护、扩展和重用。在JavaScript中,由于语言的灵活性(如原型继承和闭包),设计模式的实现方式可能与传统的基于类的OOP语言有所不同。

简介[编辑 | 编辑源代码]

设计模式最初由“四人帮”(GoF)在《设计模式:可复用面向对象软件的基础》一书中提出,分为三类:创建型结构型行为型。JavaScript的动态特性(如原型链、高阶函数和动态类型)允许开发者以更灵活的方式实现这些模式。

为什么需要设计模式?[编辑 | 编辑源代码]

  • 代码复用:避免重复解决相同问题。
  • 可维护性:提供清晰的代码结构。
  • 可扩展性:便于未来功能扩展。
  • 团队协作:提供通用的设计词汇。

创建型模式[编辑 | 编辑源代码]

创建型模式关注对象的创建机制。

工厂模式(Factory Pattern)[编辑 | 编辑源代码]

工厂模式通过一个通用接口创建对象,而不暴露具体实现逻辑。

class Car {
  constructor(model, year) {
    this.model = model;
    this.year = year;
  }
}

class CarFactory {
  createCar(model) {
    switch(model) {
      case 'sedan':
        return new Car('Toyota Camry', 2023);
      case 'suv':
        return new Car('Ford Explorer', 2023);
      default:
        throw new Error('Unknown car type');
    }
  }
}

const factory = new CarFactory();
const sedan = factory.createCar('sedan');
console.log(sedan); // 输出: Car { model: 'Toyota Camry', year: 2023 }

单例模式(Singleton Pattern)[编辑 | 编辑源代码]

单例模式确保一个类只有一个实例,并提供全局访问点。

class Database {
  constructor() {
    if (Database.instance) {
      return Database.instance;
    }
    this.connection = 'Connected to DB';
    Database.instance = this;
  }
}

const db1 = new Database();
const db2 = new Database();
console.log(db1 === db2); // 输出: true

结构型模式[编辑 | 编辑源代码]

结构型模式处理对象组合和类之间的关系。

装饰器模式(Decorator Pattern)[编辑 | 编辑源代码]

动态地为对象添加新功能,而不改变其结构。

class Coffee {
  cost() {
    return 5;
  }
}

class MilkDecorator {
  constructor(coffee) {
    this.coffee = coffee;
  }

  cost() {
    return this.coffee.cost() + 2;
  }
}

const simpleCoffee = new Coffee();
const coffeeWithMilk = new MilkDecorator(simpleCoffee);
console.log(coffeeWithMilk.cost()); // 输出: 7

适配器模式(Adapter Pattern)[编辑 | 编辑源代码]

使不兼容的接口能够协同工作。

class OldCalculator {
  operations(a, b, operation) {
    switch(operation) {
      case 'add':
        return a + b;
      case 'sub':
        return a - b;
      default:
        return NaN;
    }
  }
}

class NewCalculator {
  add(a, b) {
    return a + b;
  }
  sub(a, b) {
    return a - b;
  }
}

class CalculatorAdapter {
  constructor() {
    this.calculator = new NewCalculator();
  }

  operations(a, b, operation) {
    switch(operation) {
      case 'add':
        return this.calculator.add(a, b);
      case 'sub':
        return this.calculator.sub(a, b);
      default:
        return NaN;
    }
  }
}

const adapter = new CalculatorAdapter();
console.log(adapter.operations(5, 3, 'add')); // 输出: 8

行为型模式[编辑 | 编辑源代码]

行为型模式关注对象间的通信和职责分配。

观察者模式(Observer Pattern)[编辑 | 编辑源代码]

定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖者自动收到通知。

class Subject {
  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(`Received data: ${data}`);
  }
}

const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();

subject.subscribe(observer1);
subject.subscribe(observer2);
subject.notify('Hello World!');
// 输出:
// Received data: Hello World!
// Received data: Hello World!

策略模式(Strategy Pattern)[编辑 | 编辑源代码]

定义一系列算法,封装每个算法,并使它们可以互换。

class PaymentStrategy {
  pay(amount) {}
}

class CreditCardStrategy extends PaymentStrategy {
  pay(amount) {
    console.log(`Paid ${amount} via Credit Card`);
  }
}

class PayPalStrategy extends PaymentStrategy {
  pay(amount) {
    console.log(`Paid ${amount} via PayPal`);
  }
}

class ShoppingCart {
  constructor() {
    this.strategy = null;
  }

  setStrategy(strategy) {
    this.strategy = strategy;
  }

  checkout(amount) {
    this.strategy.pay(amount);
  }
}

const cart = new ShoppingCart();
cart.setStrategy(new CreditCardStrategy());
cart.checkout(100); // 输出: Paid 100 via Credit Card

实际应用案例[编辑 | 编辑源代码]

案例1:电商平台的支付系统(策略模式)[编辑 | 编辑源代码]

电商平台需要支持多种支付方式(信用卡、PayPal、加密货币等)。使用策略模式可以轻松添加新的支付方式而不修改现有代码。

案例2:实时数据仪表盘(观察者模式)[编辑 | 编辑源代码]

多个UI组件需要实时显示来自同一数据源的信息。观察者模式确保所有组件在数据更新时自动刷新。

设计模式关系图[编辑 | 编辑源代码]

graph TD A[设计模式] --> B[创建型] A --> C[结构型] A --> D[行为型] B --> E[工厂模式] B --> F[单例模式] C --> G[装饰器模式] C --> H[适配器模式] D --> I[观察者模式] D --> J[策略模式]

数学基础[编辑 | 编辑源代码]

某些模式(如状态模式)涉及状态转换,可以用数学表示:

Sn+1=f(Sn,In)

其中:

  • Sn 是当前状态
  • In 是输入
  • f 是转换函数

总结[编辑 | 编辑源代码]

JavaScript设计模式提供了解决常见问题的模板。关键要点:

  • 根据需求选择合适的模式
  • JavaScript的实现可能与传统OOP语言不同
  • 模式可以组合使用
  • 避免过度设计 - 只在必要时使用模式

通过掌握这些模式,开发者可以编写更健壮、可维护的JavaScript代码。