工厂模式

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('Subclass must implement 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');

抽象工厂

// 抽象工厂:创建一系列相关产品
class UIFactory {
  createButton() {
    throw new Error('Must implement');
  }
  createInput() {
    throw new Error('Must implement');
  }
}

// iOS 风格工厂
class IOSFactory extends UIFactory {
  createButton() {
    return { type: 'ios-button', style: 'tckc3' };
  }
  createInput() {
    return { type: 'ios-input', style: 'minimal' };
  }
}

// Android 风格工厂
class AndroidFactory extends UIFactory {
  createButton() {
    return { type: 'android-button', style: 'material' };
  }
  createInput() {
    return { type: 'android-input', style: 'outlined' };
  }
}

// 使用:根据平台选择工厂
function createUI(platform) {
  const factory = platform === 'ios' ? new IOSFactory() : new AndroidFactory();
  return {
    button: factory.createButton(),
    input: factory.createInput()
  };
}

console.log(createUI('ios'));
// { button: { type: 'ios-button', style: 'tckc3' }, input: { type: 'ios-input', style: 'minimal' } }

实际应用:React 组件工厂

// 根据配置动态创建表单组件
const componentMap = {
  text: (props) => <input type="text" {...props} />,
  select: (props) => (
    <select {...props}>
      {props.options.map(opt => <option key={opt.value} value={opt.value}>{opt.label}</option>)}
    </select>
  ),
  checkbox: (props) => <input type="checkbox" {...props} />
};

function FormFieldFactory({ type, ...props }) {
  const Component = componentMap[type];
  if (!Component) {
    return null;
  }
  return Component(props);
}

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

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

关键点

  • 简单工厂:一个函数根据参数创建不同对象,适合产品类型少的场景
  • 工厂方法:每种产品对应一个工厂类,符合开闭原则,便于扩展
  • 抽象工厂:创建一系列相关产品,适合有产品族的场景
  • 使用场景:创建逻辑复杂、需要解耦、动态决定创建哪种对象时使用
  • 前端常见应用:动态表单生成、跨平台组件、插件系统