设计模式-生成器

38 阅读1分钟

定义

构建器模式,是一种创建型设计模式,用于构造复杂对象。它将要给复杂对象的构造过程从其表示中分离出来,使得同样的构建过程可以创建不同表示。

UML 图

typescript 实现

1. 定义 Product1 类

class Product1 {
  private parts: string[] = [];
  public add(part: string): void {
    this.parts.push(part);
  }
  public show(): void {
    console.log(`Product Parts: ${this.parts.join(',')}`);
  }
}

2. 创建 Builder 接口

interface Builder {
  reset(): void;
  buildPartA(): void;
  buildPartB(): void;
  buildPartC(): void;
}

3. 创建具体 Builder 类

class ConcreteBuilder1 implements Builder {
  private product: Product1;
  constructor() {
    this.reset();
  }
  public reset(): void {
    this.product = new Product1();
  }
  public buildPartA(): void {
    this.product.add("PartA");
  }
  public buildPartB(): void {
    this.product.add("PartB");
  }
  public buildPartC(): void {
    this.product.add("PartC");
  }
  public getResult(): Product1 {
    return this.product;
  }
}

4. 创建 Director

class Director {
  private builder: Builder;
  public setBuilder(builder: Builder): void {
    this.builder = builder;
  }
  public make(type: string): void {
    if(type === "full") {
      this.buildFullFeatureProduct();
    }
    if(type === "mini") {
      this.buildMinimalViableProduct();
    }
  }
  public buildFullFeatureProduct(): void {
    this.builder.buildPartA();
    this.builder.buildPartB();
    this.builder.buildPartC();
  }
  public buildMinimalViableProduct(): void {
    this.builder.buildPartA();
  }
}

5. 使用示例

const director = new Director();
const builder = new ConcreteBuilder1();
director.setBuilder(builder);

console.log("Standard basic product:");
builder.getResult().show();

console.log("Standard full featured product:");
director.make("full");
builder.getResult().show();

console.log("Custom product:");
builder.buildPartA();
builder.buildPartB();
builder.getResult().show();

通用的生成器

// 公共的 Builder
export abstract class Builder<T> {
  protected result!: T;
  getResult(): T;
}
// 公共的 Director
export abstract class Director<T> {
  protected builder: T | undefined;
  protected constructor(builder?: T) {
    this.builder = builder;
  }
  setBuilder(builder: T) {
    this.builder = builder;
  }
}

// 私有的 Trip
class Trip {  
  public destination: string;  
  public days: number;  
  public description: string;  
  public price: number;  
  constructor(destination?: string, days?: number, description?: string, price?: number) {    
    this.destination = destination || 'Suzhou';
    this.days = days || 3;
    this.description = description || "fuck good";
    this.price = price || 3000;
  }
}
// 私有的 TripBuilderclass TripBuilder extends Builder<Trip> {
  constructor() {
    super();
    this.result = new Trip();
  }
  setDestination(destination: string) {
    this.result.destination = destination;
    return this;
  }
  setDays(days: number) {
    this.result.days = days;
    return this;
  }
  setDescription(description: string) {
    this.result.description = description;
    return this;
  }
  setPrice(price: number) {
    this.result.price = price;
    return this;
  }
  getResult(): Trip {
    return this.result;
  }
}

// 私有的 TripBuilder
class TripDirector extends Director<TripBuilder> {
  constructor() {
    super();
  }
  createTop1() {
    this.builder
      ?.setDestination("Beijing")
      .setDays(7)
      .setPrice(39999)
      .setDescription("good")
  }
}

// 私有,示例
const tripDirector = new TripDirector();
const tripBuilder = new TripBuilder();
tripDirector.setBuilder(tripBuilder);
tripDirector.buildTop1();
const top1 = tripBuilder.getResult();