你的程序中可能会 // 有多个以不同方式实现的生成器变体。 class CarBuilder implements Builder is private field car:Car // 一个新的生成器实例必须包含一个在后续组装过程中使用的空产品对象。 constructor CarBuilder() is this.reset() // reset(重置)方法可清除正在生成的对象。 method reset() is this.car = new Car() // 所有生成步骤都会与同一个产品实例进行交互。 method setSeats(...) is // 设置汽车座位的数量。 method setEngine(...) is // 安装指定的引擎。 method setTripComputer(...) is // 安装行车电脑。 method setGPS(...) is // 安装全球定位系统。 // 具体生成器需要自行提供获取结果的方法。这是因为不同类型的生成器可能 // 会创建不遵循相同接口的、完全不同的产品。所以也就无法在生成器接口中 // 声明这些方法(至少在静态类型的编程语言中是这样的)。 // // 通常在生成器实例将结果返回给客户端后,它们应该做好生成另一个产品的 // 准备。因此生成器实例通常会在 `getProduct(获取产品)`方法主体末尾 // 调用重置方法。但是该行为并不是必需的,你也可让生成器等待客户端明确 // 调用重置方法后再去处理之前的结果。 method getProduct():Car is product = this.car this.reset() return product // 生成器与其他创建型模式的不同之处在于:它让你能创建不遵循相同接口的产品。 class CarManualBuilder implements Builder is private field manual:Manual constructor CarManualBuilder() is this.reset() method reset() is this.manual = new Manual() method setSeats(...) is // 添加关于汽车座椅功能的文档。 method setEngine(...) is // 添加关于引擎的介绍。 method setTripComputer(...) is // 添加关于行车电脑的介绍。 method setGPS(...) is // 添加关于 GPS 的介绍。 method getProduct():Manual is // 返回使用手册并重置生成器。 // 主管只负责按照特定顺序执行生成步骤。其在根据特定步骤或配置来生成产品时 // 会很有帮助。由于客户端可以直接控制生成器,所以严格意义上来说,主管类并 // 不是必需的。 class Director is private field builder:Builder // 主管可同由客户端代码传递给自身的任何生成器实例进行交互。客户端可通 // 过这种方式改变最新组装完毕的产品的最终类型。 method setBuilder(builder:Builder) this.builder = builder // 主管可使用同样的生成步骤创建多个产品变体。 method constructSportsCar(builder: Builder) is builder.reset() builder.setSeats(2) builder.setEngine(new SportEngine()) builder.setTripComputer(true) builder.setGPS(true) method constructSUV(builder: Builder) is // ... // 客户端代码会创建生成器对象并将其传递给主管,然后执行构造过程。最终结果 // 将需要从生成器对象中获取。 class Application is method makeCar() is director = new Director() CarBuilder builder = new CarBuilder() director.constructSportsCar(builder) Car car = builder.getProduct() CarManualBuilder builder = new CarManualBuilder() director.constructSportsCar(builder) // 最终产品通常需要从生成器对象中获取,因为主管不知晓具体生成器和 // 产品的存在,也不会对其产生依赖。 Manual manual = builder.getProduct()

适合应用场景

使用生成器模式可避免“重叠构造函数(telescopic constructor)”的出现。
假设你的构造函数中有十个可选参数,那么调用该函数会非常不方便;因此,你需要重载这个构造函数,新建几个只有较少参数的简化版。但这些构造函数仍需调用主构造函数,传递一些默认数值来替代省略掉的参数。