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