工厂模式提供了一种方式来创建对象,同时隐藏了对象创建的具体实现细节。它通过一个工厂函数或方法来封装对象的创建过程,从而使客户端代码与具体对象的实例化过程解耦,提高了代码的灵活性和可维护性。
在JavaScript中,工厂模式通常有以下几种变体:
- 简单工厂模式:使用一个工厂函数根据传入的参数来创建不同类型的对象。
- 工厂方法模式:定义一个用于创建对象的接口,但将对象的实际创建延迟到子类中。
- 抽象工厂模式:提供一个接口,用于创建一系列相关或依赖对象的家族,而不需要指定具体类。
1. 简单工厂模式:
简单工厂模式通过一个工厂函数来创建不同类型的对象。这个工厂函数根据传入的参数或条件来决定创建哪种类型的对象。
function createProduct(type) {
switch (type) {
case 'A':
return new ProductA();
case 'B':
return new ProductB();
default:
throw new Error('Unknown product type');
}
}
function ProductA() {
this.name = 'Product A';
}
function ProductB() {
this.name = 'Product B';
}
// 使用工厂函数创建对象
var productA = createProduct('A');
var productB = createProduct('B');
console.log(productA.name); // 输出: Product A
console.log(productB.name); // 输出: Product B
2. 工厂方法模式:
工厂方法模式定义了一个用于创建对象的接口,但将对象的实际创建延迟到子类中。每个子类都可以实现工厂方法来创建特定类型的对象。
// 抽象工厂
function Factory() {}
// 工厂方法
Factory.prototype.createProduct = function() {
throw new Error('This method should be overridden by subclasses');
};
// 具体工厂子类
function ConcreteFactoryA() {}
ConcreteFactoryA.prototype = Object.create(Factory.prototype);
ConcreteFactoryA.prototype.createProduct = function() {
return new ProductA();
};
function ConcreteFactoryB() {}
ConcreteFactoryB.prototype = Object.create(Factory.prototype);
ConcreteFactoryB.prototype.createProduct = function() {
return new ProductB();
};
// 具体产品类
function ProductA() {
this.name = 'Product A';
}
function ProductB() {
this.name = 'Product B';
}
// 使用具体工厂创建对象
var factoryA = new ConcreteFactoryA();
var productA = factoryA.createProduct();
console.log(productA.name); // 输出: Product A
var factoryB = new ConcreteFactoryB();
var productB = factoryB.createProduct();
console.log(productB.name); // 输出: Product B
3. 抽象工厂模式:
抽象工厂模式提供一个接口,用于创建一系列相关或依赖对象的家族,而不需要指定具体类。每个具体工厂子类负责创建特定类型的对象家族。
// 抽象工厂
function AbstractFactory() {}
// 工厂方法
AbstractFactory.prototype.createProductA = function() {
throw new Error('This method should be overridden by subclasses');
};
AbstractFactory.prototype.createProductB = function() {
throw new Error('This method should be overridden by subclasses');
};
// 具体工厂子类
function ConcreteFactory1() {}
ConcreteFactory1.prototype = Object.create(AbstractFactory.prototype);
ConcreteFactory1.prototype.createProductA = function() {
return new ProductA1();
};
ConcreteFactory1.prototype.createProductB = function() {
return new ProductB1();
};
function ConcreteFactory2() {}
ConcreteFactory2.prototype = Object.create(AbstractFactory.prototype);
ConcreteFactory2.prototype.createProductA = function() {
return new ProductA2();
};
ConcreteFactory2.prototype.createProductB = function() {
return new ProductB2();
};
// 具体产品类
function ProductA1() {
this.name = 'Product A1';
}
function ProductB1() {
this.name = 'Product B1';
}
function ProductA2() {
this.name = 'Product A2';
}
function ProductB2() {
this.name = 'Product B2';
}
// 使用具体工厂创建对象
var factory1 = new ConcreteFactory1();
var productA1 = factory1.createProductA();
console.log(productA1.name); // 输出: Product A1
var factory2 = new ConcreteFactory2();
var productB2 = factory2.createProductB();
console.log(productB2.name); // 输出: Product B2
这个比喻可以帮助理解工厂模式和抽象工厂模式之间的区别:
- 工厂方法模式(Factory Method Pattern): 在这个比喻中,每个餐品都对应着一个单独的厨房窗口(工厂方法 ),每个窗口负责生产特定类型的餐品。例如,一个窗口可能负责生产汉堡,另一个窗口负责生产披萨。每个窗口可以有自己独特的生产工艺和配料组合,但它们都遵循相同的生产流程。
- 抽象工厂模式(Abstract Factory Pattern): 在这个比喻中,只有一个统一的厨房窗口,但这个窗口可以生产多种类型的餐品。每个餐品的生产过程可能涉及到多个步骤和多个厨房工具,而这个厨房窗口(抽象工厂)负责协调这些步骤并生产出不同类型的餐品。例如,这个厨房可以生产汉堡、披萨和沙拉,每个餐品都有自己的特定配料和制作方式。
文章评论