意图
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
动机
问题
一个RTF文档有多种转换方式,未来会增加新的转换方式。
解决方式
封装转换器,传给给RTF阅读器,让RTF阅读器进行语法分析提炼出各个部件,然后把各个部件的构造或装配工作委托给转换器,这样可以重用阅读器的语法分析的算法。
示例图形
适用性
- 对于一个拥有许多组成部件的复杂对象,想要将此复杂对象的创建算法和其组成部件的装配(构造)方式独立开来时。
- 当构造过程必须允许被构造的对象的组成部件有不同的表示时。
结构
参与者
- Builder:为创建一个产品对象的各个部件指定抽象接口。
- ConcreteBuilder:
- 实现Builder声明的接口以构造和装配该产品的各个部件。
- 提供一个获取最终产品的接口。
- Director(导向器):将复杂对象的各个部件的构造和装配委托给某个ConcreteBuilder。
- Product:由ConcreteBuilder最终构造完成的复杂对象。
协作
- 客户创建Director和Builder,用Builder来配置Director。
- 一旦产品部件被生成,Director会将部件发送给Builder。
- Builder处理Director的请求,并且将部件装配到产品中。
- 客户从Builder中获取产品。
-
交互图:
效果
- 可以通过定义一个新的ConcreteBuilder改变一个产品的各个部件表现形式。
- 将构造代码和表示代码分开,使得容易增加新的构造方式或者新的表示形式。
- 可以通过定义一个新的ConcreteBuilder来对复杂对象构造过程进行更精细的控制。
实现
- Builder提供的接口必须足够普遍,以便ConcreteBuilder重写。
- 若构造一个新部件需要访问前面已经构造了的部件,可以让Builder将部件返回给Director,然后Director又将部件回传给Builder去生成新部件。
- Builder中的方法不应该声明为纯虚成员函数,这样客户可以只重定义他们感兴趣的操作而不是所有操作。
- 不定义产品抽象类,因为用ConcreteBuilder生成的具体产品通常差别很大,而因为ConcreteBuilder是客户定义的,所以客户通常知道生成的产品是怎样的。