js设计模式之工厂模式

98 阅读2分钟

1.png

什么是工厂模式

工厂模式其实就是封装对象的创建过程,使得创建对象的逻辑与使用对象的逻辑分离开来。

工厂模式玩法

看看一个可以造摩托车和小汽车的工厂用工厂模式怎么表达

3.png


// 定义基础类
class Vehicle {
  constructor(make, model, year) {
    this.make = make;
    this.model = model;
    this.year = year;
  }

  getInfo() {
    return `Make: ${this.make}, Model: ${this.model}, Year: ${this.year}`;
  }
}

// 定义不同类型的子类
class Car extends Vehicle {
  constructor(make, model, year) {
    super(make, model, year);
    this.type = "Car";
  }

  getVehicleType() {
    return this.type;
  }
}

class Motorcycle extends Vehicle {
  constructor(make, model, year) {
    super(make, model, year);
    this.type = "Motorcycle";
  }

  getVehicleType() {
    return this.type;
  }
}

// 定义工厂类
class VehicleFactory {
  createVehicle(type, make, model, year) {
    switch (type) {
      case "Car":
        return new Car(make, model, year);
      case "Motorcycle":
        return new Motorcycle(make, model, year);
      default:
        throw new Error("Invalid vehicle type.");
    }
  }
}

// 使用工厂模式创建对象
const factory = new VehicleFactory();
const car1 = factory.createVehicle("Car", "Toyota", "Camry", 2020);
const car2 = factory.createVehicle("Car", "Honda", "Accord", 2019);
const motorcycle1 = factory.createVehicle("Motorcycle", "Harley-Davidson", "Sportster", 2021);

console.log(car1.getInfo()); // 输出:Make: Toyota, Model: Camry, Year: 2020
console.log(car2.getInfo()); // 输出:Make: Honda, Model: Accord, Year: 2019
console.log(motorcycle1.getInfo()); // 输出:Make: Harley-Davidson, Model: Sportster, Year: 2021
console.log(motorcycle1.getVehicleType()); // 输出:Motorcycle

更加安全的工厂模式玩法


// 定义工厂类
class VehicleFactory {
  // 私有函数,用于创建 Car 对象
  static createCar(make, model, year) {
    return {
      make: make,
      model: model,
      year: year,
      getInfo: function() {
        return `Make: ${this.make}, Model: ${this.model}, Year: ${this.year}`;
      }
    };
  }

  // 私有函数,用于创建 Motorcycle 对象
  static createMotorcycle(make, model, year) {
    return {
      make: make,
      model: model,
      year: year,
      getInfo: function() {
        return `Make: ${this.make}, Model: ${this.model}, Year: ${this.year}`;
      }
    };
  }

  // 公共函数,用于创建对象
  static createVehicle(type, make, model, year) {
    switch (type) {
      case "Car":
        return VehicleFactory.createCar(make, model, year);
      case "Motorcycle":
        return VehicleFactory.createMotorcycle(make, model, year);
      default:
        throw new Error("Invalid vehicle type.");
    }
  }
}

// 使用工厂模式创建对象
const car1 = VehicleFactory.createVehicle("Car", "Toyota", "Camry", 2020);
const car2 = VehicleFactory.createVehicle("Car", "Honda", "Accord", 2019);
const motorcycle1 = VehicleFactory.createVehicle("Motorcycle", "Harley-Davidson", "Sportster", 2021);

console.log(car1.getInfo()); // 输出:Make: Toyota, Model: Camry, Year: 2020
console.log(car2.getInfo()); // 输出:Make: Honda, Model: Accord, Year: 2019
console.log(motorcycle1.getInfo()); // 输出:Make: Harley-Davidson, Model: Sportster, Year: 2021

安全工厂模式玩法的好处

  • 避免使用new关键字。在JavaScript中,使用new关键字创建对象可能会带来一些安全问题,例如可能会被恶意代码利用创建一个用于攻击的对象。安全工厂方法避免了使用new,从而减少了这种风险。
  • 可以实现封装和隐藏实现。安全工厂方法可以将关键的创建对象的代码封装在内部,从而隐藏实现细节,提高代码的安全性和可维护性。
  • 更易于维护。由于安全工厂方法可以提供统一的访问接口,因此更容易进行代码的维护和升级。
  • 可以提高代码的可测试性。由于安全工厂方法可以实现封装和隐藏实现,因此可以更轻松地进行单元测试和集成测试,从而提高代码的质量和可测试性。