1.意图
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
2.动机
一个RTF(Rich Text Format)文档交换格式的阅读器应能将RTF转换为普通ASCII文本或转换成一个能以交互方式编辑的正文窗口组件。但问题在于可能转换的数目是无限的,因此要很容易实现新的转换的增加,同时却不改变RTF阅读器。
一个解决方法是用一个可以将RTF转换为另一种正文表示的TextConverter对象配置这个RTFReader类。当RTFReader对RTF文档进行语法分析时,它使用TextConverter去做转换。无论何时RTFReader识别了一个RTF标记,它都发送一个请求给TextConverter去转换这个标记。TextConverter对象负责进行数据转换以及特定格式表示该标记,如下图所示:
TextConverter的子类对不同转换和不同格式进行特殊处理。每种转换器类创建和装配一个复杂对象的机制隐含在抽象接口的后面。转换器独立于阅读器,阅读器负责对一个RTF文档进行语法分析。
Builder模式描述了所有这些关系,每一个转换器类在该模式中被称为生成器。而阅读器则称为导向器。在上面的例子中,Build模式将分析文本格式的算法与描述怎样创建和表示一个转换后格式的算法分离开来。这使我们可以重用RTFReader的语法分析算法,根据RTF文档创建不同的正文表示——仅需使用不同的TextConverter的子类配置该RTFReader即可。
3.适用性
在以下情况使用Builder模式
- 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时;
- 当构造过程必须允许被构造的对象有不同的表示时。
4 结构
此模式结构如图所示:
5 参与者
- Builder(TextConverter)——为创建一个Product对象的各个部件指定对象接口;
- ConcreteBuilder(ASCIIConverter、TeXConverter、TextWidgetConverter)——实现Builder的接口以构造和装配该产品的各个部件;定义并明确它创建的表示;提供一个检索产品的接口;
- Director(RTFReader)——构造一个使用Builder接口的对象;
- Product(ASCIIText、TeXText、TextWidget)——表示被构造的复杂对象,ConcreteBuilder创建该产品的内部表示并定义它的装配过程;包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
6 协作
- 客户创建Director对象,并用它所想要的Builder对象进行配置
- 一旦产品部件被生成,导向器会通知生成器
- 生成器处理导向器的请求,并将部件添加到该产品中
-
客户从生成器中检索产品
交互图如下:
7 效果
- 1.它使你可以改变一个产品的内部表示:Builder对象提供给导向器一个构造产品的抽象接口。该接口使得生成器可以隐藏这个产品的表示和内部结构。它同时也隐藏了该产品是如何装配的。
- 2.它将构造代码和表示代码分开:Builder模式通过封装一个复杂对象的创建和表示方式提高了对象的模块性。
- 3.它使你可对构造过程进行更精细的控制:Builder模式与一下子就生成产品的创建型模式不同,它是在导向者的控制下一步一步构造产品的。仅当该产品完成时导向者才从生成器中取回它。因此Builder接口相比其他创建型模式能更好的反映产品的构造过程。这使你可以更精细的控制构建过程,从而能更精细的控制所得产品的内部结构。
8.实现
通常有一个抽象的Builder类为导向者可能要求创建的每一个构件定义一个操作。这些操作缺省情况下什么都不做。一个ConcreteBuilder类对它有兴趣创建的构件重定义这些操作。
- 1 装配和构造接口:生成器逐步的构造它们的产品。因此Builder类接口必须足够普遍,以便为各种类型的具体生成器构造产品。
- 2 为什么产品没有抽象类:通常情况下,由具体生成器生成的产品,它们的表示相差是如此之大以至于给不同的产品以公共父类没有太大意思。
- 3 在Builder中缺省的方法为空。