在前端开发中,工厂设计模式(Factory Pattern)是一种非常有用的设计模式,能够帮助我们在创建对象时减少代码的重复性和复杂性。
一、工厂设计模式概述
工厂设计模式是一种创建型设计模式,主要目的是定义一个用于创建对象的接口,让子类决定实例化哪个类。通过这种方式,客户端在不指定具体类的情况下创建对象,从而提高代码的灵活性和可维护性。
工厂设计模式可以分为以下几种类型:
- 简单工厂模式:又称为静态工厂方法模式,工厂类决定创建哪一个产品类的实例。
- 工厂方法模式:定义一个创建对象的接口,但由子类决定实例化哪个类。
- 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
二、简单工厂模式
简单工厂模式通过一个工厂类来决定创建哪种具体产品类的实例。这个工厂类包含一个静态方法,根据传入的参数决定要创建的对象类型。
// 抽象产品
interface Product {
use(): void;
}
// 具体产品A
class ConcreteProductA implements Product {
use(): void {
console.log("Using ConcreteProductA");
}
}
// 具体产品B
class ConcreteProductB implements Product {
use(): void {
console.log("Using ConcreteProductB");
}
}
// 简单工厂
class SimpleFactory {
static createProduct(type: string): Product {
switch (type) {
case 'A':
return new ConcreteProductA();
case 'B':
return new ConcreteProductB();
default:
throw new Error("Invalid product type");
}
}
}
// 测试
const productA = SimpleFactory.createProduct('A');
productA.use(); // 输出:Using ConcreteProductA
const productB = SimpleFactory.createProduct('B');
productB.use(); // 输出:Using ConcreteProductB
类图
三、工厂方法模式
工厂方法模式将对象的实例化推迟到子类,通过子类来决定创建哪种具体产品类的实例。这个模式使得工厂类的设计更加灵活和可扩展。
// 抽象产品
interface Product {
use(): void;
}
// 具体产品A
class ConcreteProductA implements Product {
use(): void {
console.log("Using ConcreteProductA");
}
}
// 具体产品B
class ConcreteProductB implements Product {
use(): void {
console.log("Using ConcreteProductB");
}
}
// 抽象工厂
interface Creator {
factoryMethod(): Product;
}
// 具体工厂A
class ConcreteCreatorA implements Creator {
factoryMethod(): Product {
return new ConcreteProductA();
}
}
// 具体工厂B
class ConcreteCreatorB implements Creator {
factoryMethod(): Product {
return new ConcreteProductB();
}
}
// 使用工厂方法模式
function clientCode(factory: Creator) {
const computer = factory.factoryMethod();
computer.use();
}
// 测试
clientCode(new ConcreteCreatorA()) // 输出:Using ConcreteProductA
clientCode(new ConcreteCreatorB()) // 输出:Using ConcreteProductB
类图
三、抽象工厂模式
抽象工厂模式用于创建相关或依赖的对象族,而不需要指定具体类。它提供一个接口,用于创建一组相关或互相依赖的对象。
// 抽象产品A
interface AbstractProductA {
use(): void;
}
// 抽象产品B
interface AbstractProductB {
eat(): void;
}
// 具体产品A1
class ConcreteProductA1 implements AbstractProductA {
use(): void {
console.log("Using ConcreteProductA1");
}
}
// 具体产品A2
class ConcreteProductA2 implements AbstractProductA {
use(): void {
console.log("Using ConcreteProductA2");
}
}
// 具体产品B1
class ConcreteProductB1 implements AbstractProductB {
eat(): void {
console.log("Eating ConcreteProductB1");
}
}
// 具体产品B2
class ConcreteProductB2 implements AbstractProductB {
eat(): void {
console.log("Eating ConcreteProductB2");
}
}
// 抽象工厂
interface AbstractFactory {
createProductA(): AbstractProductA;
createProductB(): AbstractProductB;
}
// 具体工厂1
class ConcreteFactory1 implements AbstractFactory {
createProductA(): AbstractProductA {
return new ConcreteProductA1();
}
createProductB(): AbstractProductB {
return new ConcreteProductB1();
}
}
// 具体工厂2
class ConcreteFactory2 implements AbstractFactory {
createProductA(): AbstractProductA {
return new ConcreteProductA2();
}
createProductB(): AbstractProductB {
return new ConcreteProductB2();
}
}
// 使用抽象工厂模式
function clientCode(factory: AbstractFactory) {
const productA = factory.createProductA();
const productB = factory.createProductB();
productA.use();
productB.eat();
}
// 测试
clientCode(new ConcreteFactory1()); // 输出:Using ConcreteProductA1 和 Eating ConcreteProductB1
clientCode(new ConcreteFactory2()); // 输出:Using ConcreteProductA2 和 Eating ConcreteProductB2
类图
四、工厂设计模式的应用场景
工厂设计模式适用于以下场景:
- 对象的创建过程复杂:当一个类的实例化过程比较复杂时,使用工厂模式可以简化客户端的代码。
- 需要大量创建相似对象:例如需要创建多个具有相同属性但行为不同的对象时,可以使用工厂模式。
- 系统的扩展性要求较高:当系统需要灵活地增加新功能时,工厂模式有助于降低代码的耦合度。