建造者模式

参考

  1. 生成器模式

  2. 建造者模式(Builder模式)详解

  3. 工厂方法模式VS建造者模式

定义

亦称,生成器模式、Builder模式。将一个复杂对象的构造与它的表示分离,能够使用相同的代码生成不同了类型的对象。它是将一个复杂的对象创建过程分解为一个个简单的步骤、对象,然后一步步构成。

应用场景

  1. 需要生成的对象有复杂的内部结构,获取、生成正确类型的对象步骤相对复杂、繁琐。

  2. 相同的方法,不同的执行顺序,会产生不同的结果,执行顺序需要能够灵活调整、扩展。

  3. 多个组件、属性都可以装配到同一个对象中,产生不同的对象。

    如一家咖啡店能制作多种咖啡,每种咖啡的制作步骤、原料添加都有所不同。如果让客户(client)去负责咖啡的调制那这家店可以倒闭了,所以咖啡店都有专门的咖啡师(director)来负责咖啡的制作,客户点单即可。所有咖啡有基本的制作模板,比如加咖啡豆、加水、加奶等等,咖啡师根据不同咖啡的不同制作步骤、不同原料来制作一杯咖啡。

实现、应用思路

  1. 产品类(Product):最终生成的产品或期间用于组装产品的子部件。

  2. 抽象建造类(Builder):包含创建产品各个子部件的抽象方法的接口,通常有一个用于返回复杂产品的方法。

  3. 具体建造者类(Concrete Builder):实现抽象建造类接口,完成复杂产品的各个具体创建步骤。

  4. 指挥者、主管类(Director):定义按照特定顺序,调用构建者中的构造、装配方法,来完成复杂对象的创建。

优点

  1. 低耦合,对象构建与表示分离。

  2. 扩展性好,各个具体构建者的相互独立,构建步骤可自定义,有利于系统解耦。

  3. 客户端不必谁知道对象生成细节,就能生成复杂对象

缺点

  1. 需要新增多个类,有可能让系统变得更难理解,复杂度提高。

  2. 克隆循环引用的复杂对象需要小心处理,要意识到深、浅克隆的区别。

建造者模式和工厂模式的不同

两个模式乍看之下非常相似,因为都是用于生产对象的创建型设计模式,但两者的关注点有所不同。

  1. 建造者模式要知道对象的组成部分,更关注对象的创建步骤、组装,而工厂模式的关注点在于创建对象即可。

  2. 建造者模式适用于创建复杂、各有差异的对象,而工厂模式生产的是一样的对象。

代码实例

// 抽象产品
export abstract class Coffee {
  abstract bean: number
  abstract water: number
  abstract milk: number
  abstract price: number
}
// 具体产品,美式咖啡
class American extends Coffee {
  bean = 0
  water = 0
  milk = 0
  price = 10
}
// 具体产品,拿铁咖啡
class Latte extends Coffee {
  bean = 0
  water = 0
  milk = 0
  price = 20
}
// 抽象建造者
abstract class CoffeeBuilder {
  abstract type: string
  abstract coffee: Coffee
  abstract addCoffeeBean(grams: number): void
  abstract addWater(grams: number): void
  abstract addMilk(grams: number): void
  getCoffee() {
    return this.coffee
  }
}
// 具体建造者,美式建造者
class AmericanBuilder extends CoffeeBuilder {
  type: string = 'AmericanCoffee'
  coffee: Coffee
  constructor() {
    super()
    this.coffee = new American()
  }
  addCoffeeBean() {
    this.coffee.bean = 3
  }
  addWater() {
    this.coffee.water = 3
  }
  addMilk() {
    this.coffee.milk = 0
  }
}
// 具体建造者,拿铁建造者
class LatteBuilder extends CoffeeBuilder {
  type: string = 'LatteCoffee'
  coffee: Coffee
  constructor() {
    super()
    this.coffee = new Latte()
  }
  addCoffeeBean() {
    this.coffee.bean = 2
  }
  addWater() {
    this.coffee.water = 2
  }
  addMilk() {
    this.coffee.milk = 2
  }
}
// 主管类
class Director {
  makeAmerican() {
    const americanBuilder = new AmericanBuilder()
    americanBuilder.addCoffeeBean()
    americanBuilder.addWater()
    americanBuilder.addMilk()
    return americanBuilder.getCoffee()
  }
  makeLatte() {
    const latteBuilder = new LatteBuilder()
    latteBuilder.addCoffeeBean()
    latteBuilder.addWater()
    latteBuilder.addMilk()
    return latteBuilder.getCoffee()
  }
}
// 客户端
class Client {
  constructor() {
    const director = new Director()
    const american = director.makeAmerican()
    const latte = director.makeLatte()
    console.log(american, latte)
  }
}

new Client()
上次更新: 1/12/2021, 3:06:16 PM