定义:提供一个创建一系列相关或依赖对象的接口,而无需指定它们具体的类

类比:去买家具,一个家具套装包括桌子、椅子、沙发等,可以选择现代风格或者古典风格,整个套装都是统一风格的

应用场景

  • 需要创建一系列相关或相互依赖的对象
  • 系统需要独立于产品的具体类工作

优缺点

  • 优点:
    • 将客户端与具体类解耦
    • 符合开闭原则,增加新的具体产品族时无需修改现有代码
  • 缺点:
    • 增加系统的抽象性和复杂性
    • 增加了代码的数量,系统变得更庞大

实现代码

interface AbstractProductA {
  usefulFunctionA(): string;
}
 
class ConcreteProductA1 implements AbstractProductA {
  public usefulFunctionA(): string {
    return 'The result of the product A1.';
  }
}
 
class ConcreteProductA2 implements AbstractProductA {
  public usefulFunctionA(): string {
    return 'The result of the product A2.';
  }
}
 
interface AbstractProductB {
  usefulFunctionB(): string;
  anotherUsefulFunctionB(collaborator: AbstractProductA): string;
}
 
class ConcreteProductB1 implements AbstractProductB {
  public usefulFunctionB(): string {
    return 'The result of the product B1.';
  }
 
  public anotherUsefulFunctionB(collaborator: AbstractProductA): string {
    const result = collaborator.usefulFunctionA();
    return `The result of the B1 collaborating with (${result})`;
  }
}
 
class ConcreteProductB2 implements AbstractProductB {
  public usefulFunctionB(): string {
    return 'The result of the product B2.';
  }
 
  public anotherUsefulFunctionB(collaborator: AbstractProductA): string {
    const result = collaborator.usefulFunctionA();
    return `The result of the B2 collaborating with (${result})`;
  }
}
 
interface AbstractFactory {
  createProductA(): AbstractProductA;
  createProductB(): AbstractProductB;
}
 
class ConcreteFactory1 implements AbstractFactory {
  public createProductA(): AbstractProductA {
    return new ConcreteProductA1();
  }
 
  public createProductB(): AbstractProductB {
    return new ConcreteProductB1();
  }
}
 
class ConcreteFactory2 implements AbstractFactory {
  public createProductA(): AbstractProductA {
    return new ConcreteProductA2();
  }
 
  public createProductB(): AbstractProductB {
    return new ConcreteProductB2();
  }
}
 
function clientCode(factory: AbstractFactory) {
  const productA = factory.createProductA();
  const productB = factory.createProductB();
 
  console.log(productB.usefulFunctionB());
  console.log(productB.anotherUsefulFunctionB(productA));
}
 
clientCode(new ConcreteFactory1());
clientCode(new ConcreteFactory2());