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