class Pizza { Pizza(int size) { ... } Pizza(int size, boolean cheese) { ... } Pizza(int size, boolean cheese, boolean pepperoni) { ... } // ...
只有在 C# 或Java等支持方法重载的编程语言中才能写出如此复杂的构造函数。
生成器模式让你可以分步骤生成对象,而且允许你仅使用必须的步骤。应用该模式后,你再也不需要将几十个参数塞进构造函数里了。
当你希望使用代码创建不同形式的产品(例如石头或木头房屋)时,可使用生成器模式。
如果你需要创建的各种形式的产品,它们的制造过程相似且仅有细节上的差异,此时可使用生成器模式。
基本生成器接口中定义了所有可能的制造步骤,具体生成器将实现这些步骤来制造特定形式的产品。同时,主管类将负责管理制造步骤的顺序。
使用生成器构造组合树或其他复杂对象。
生成器模式让你能分步骤构造产品。你可以延迟执行某些步骤而不会影响最终产品。你甚至可以递归调用这些步骤,这在创建对象树时非常方便。
生成器在执行制造步骤时,不能对外发布未完成的产品。这可以避免客户端代码获取到不完整结果对象的情况。

实现方法

清晰地定义通用步骤,确保它们可以制造所有形式的产品。否则你将无法进一步实施该模式。
在基本生成器接口中声明这些步骤。
为每个形式的产品创建具体生成器类,并实现其构造步骤。
不要忘记实现获取构造结果对象的方法。你不能在生成器接口中声明该方法,因为不同生成器构造的产品可能没有公共接口,因此你就不知道该方法返回的对象类型。但是,如果所有产品都位于单一类层次中,你就可以安全地在基本接口中添加获取生成对象的方法。
考虑创建主管类。它可以使用同一生成器对象来封装多种构造产品的方式。
客户端代码会同时创建生成器和主管对象。构造开始前,客户端必须将生成器对象传递给主管对象。通常情况下,客户端只需调用主管类构造函数一次即可。主管类使用生成器对象完成后续所有制造任务。还有另一种方式,那就是客户端可以将生成器对象直接传递给主管类的制造方法。
只有在所有产品都遵循相同接口的情况下,构造结果可以直接通过主管类获取。否则,客户端应当通过生成器获取构造结果。

优缺点

你可以分步创建对象,暂缓创建步骤或递归运行创建步骤。生成不同形式的产品时,你可以复用相同的制造代码。单一职责原则。你可以将复杂构造代码从产品的业务逻辑中分离出来。
由于该模式需要新增多个类,因此代码整体复杂程度会有所增加。

与其他模式的关系

在许多设计工作的初期都会使用工厂方法(较为简单,而且可以更方便地通过子类进行定制),随后演化为使用抽象工厂、原型或生成器(更灵活但更加复杂)。
生成器重点关注如何分步生成复杂对象。抽象工厂专门用于生产一系列相关对象。抽象工厂会马上返回产品,生成器则允许你在获取产品前执行一些额外构造步骤。
你可以在创建复杂组合树时使用生成器,因为这可使其构造步骤以递归的方式运行。
你可以结合使用生成器和桥接模式:主管类负责抽象工作,各种不同的生成器负责实现工作。

代码示例

支持我们的免费网站并获得电子书!

22 个设计模式和 8 条原则的详细讲解。382 页精心编排、易于阅读且没有术语的内容。225 幅有助于理解的简明图表。9 种编程语言的代码示例档案。支持所有的设备:PDF/EPUB/MOBI/KFX 格式。了解更多……