工厂模式实现

JavaScript 中三种工厂模式的实现与应用场景

问题

用 JavaScript 实现工厂模式,包括简单工厂、工厂方法和抽象工厂。

解答

简单工厂模式

由一个工厂函数根据参数决定创建哪种产品实例。

// 产品类
class Car {
  constructor(name) {
    this.name = name;
  }
  drive() {
    console.log(`${this.name} is driving`);
  }
}

class Bike {
  constructor(name) {
    this.name = name;
  }
  ride() {
    console.log(`${this.name} is riding`);
  }
}

// 简单工厂
function vehicleFactory(type, name) {
  switch (type) {
    case 'car':
      return new Car(name);
    case 'bike':
      return new Bike(name);
    default:
      throw new Error(`Unknown vehicle type: ${type}`);
  }
}

// 使用
const car = vehicleFactory('car', 'Tesla');
const bike = vehicleFactory('bike', 'Giant');
car.drive();  // Tesla is driving
bike.ride();  // Giant is riding

工厂方法模式

定义创建对象的接口,让子类决定实例化哪个类。

// 抽象工厂类
class VehicleFactory {
  create() {
    throw new Error('子类必须实现 create 方法');
  }
}

// 具体工厂类
class CarFactory extends VehicleFactory {
  create(name) {
    return new Car(name);
  }
}

class BikeFactory extends VehicleFactory {
  create(name) {
    return new Bike(name);
  }
}

// 使用
const carFactory = new CarFactory();
const bikeFactory = new BikeFactory();

const myCar = carFactory.create('BMW');
const myBike = bikeFactory.create('Trek');

myCar.drive();  // BMW is driving
myBike.ride();  // Trek is riding

抽象工厂模式

创建一系列相关或相互依赖的对象,而无需指定具体类。

// 产品族:引擎和轮胎
class SportEngine {
  start() {
    return 'Sport engine roaring';
  }
}

class EcoEngine {
  start() {
    return 'Eco engine humming';
  }
}

class SportTire {
  grip() {
    return 'High grip tires';
  }
}

class EcoTire {
  grip() {
    return 'Low resistance tires';
  }
}

// 抽象工厂
class CarPartsFactory {
  createEngine() {
    throw new Error('子类必须实现');
  }
  createTire() {
    throw new Error('子类必须实现');
  }
}

// 具体工厂:生产一系列相关产品
class SportCarPartsFactory extends CarPartsFactory {
  createEngine() {
    return new SportEngine();
  }
  createTire() {
    return new SportTire();
  }
}

class EcoCarPartsFactory extends CarPartsFactory {
  createEngine() {
    return new EcoEngine();
  }
  createTire() {
    return new EcoTire();
  }
}

// 使用
function assembleCar(factory) {
  const engine = factory.createEngine();
  const tire = factory.createTire();
  console.log(engine.start());
  console.log(tire.grip());
}

assembleCar(new SportCarPartsFactory());
// Sport engine roaring
// High grip tires

assembleCar(new EcoCarPartsFactory());
// Eco engine humming
// Low resistance tires

实际应用:React 组件工厂

// 根据类型动态创建表单组件
const componentMap = {
  input: (props) => <input {...props} />,
  select: (props) => <select {...props}>{props.options?.map(o => 
    <option key={o.value} value={o.value}>{o.label}</option>
  )}</select>,
  textarea: (props) => <textarea {...props} />
};

function FormFieldFactory({ type, ...props }) {
  const Component = componentMap[type];
  if (!Component) {
    return <div>Unknown field type</div>;
  }
  return Component(props);
}

// 使用
const formConfig = [
  { type: 'input', name: 'username', placeholder: '用户名' },
  { type: 'select', name: 'role', options: [
    { value: 'admin', label: '管理员' },
    { value: 'user', label: '用户' }
  ]},
  { type: 'textarea', name: 'bio', placeholder: '简介' }
];

function DynamicForm() {
  return (
    <form>
      {formConfig.map((field, i) => (
        <FormFieldFactory key={i} {...field} />
      ))}
    </form>
  );
}

关键点

  • 简单工厂:一个函数根据参数创建不同实例,适合产品类型少且固定的场景
  • 工厂方法:每种产品对应一个工厂类,新增产品只需新增工厂,符合开闭原则
  • 抽象工厂:创建产品族,保证一系列相关对象的一致性
  • 使用场景:对象创建逻辑复杂、需要解耦创建和使用、需要统一管理对象创建
  • 前端应用:动态组件渲染、主题切换、跨平台适配