设计模式3-创建型模式-Builder模式

意图:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

引用设计模式精解中的一段话:

生活中有着很多的Builder的例子,个人觉得大学生活就是一个Builder模式的最好体验:
要完成大学教育,一般将大学教育过程分成4个学期进行,因此没有学习可以看作是构建完
整大学教育的一个部分构建过程,每个人经过这4年的(4个阶段)构建过程得到的最后的
结果不一样,因为可能在四个阶段的构建中引入了很多的参数(每个人的机会和际遇不完全
相同)。
Builder模式要解决的也正是这样的问题:当我们要创建的对象很复杂的时候(通常是
由很多其他的对象组合而成),我们要要复杂对象的创建过程和这个对象的表示(展示)分
离开来,这样做的好处就是通过一步步的进行复杂对象的构建,由于在每一步的构造过程中
可以引入参数,使得经过相同的步骤创建最后得到的对象的展示不一样。

 

Builder模式的核心思想

  将一个“复杂对象的构建算法”与它的“部件及组装方式”分离,使得构件算法和组装方式可以独立应对变化;
  复用同样的构建算法可以创建不同的表示,不同的构建过程可以复用相同的部件组装方式。

  抽象的Builder类,为导向者可能要求创建的每一个构件(Part)定义一个操作(接口)。这些操作缺省情况下什么都不做。
  一个ConcreteBuilder类对它所感兴趣的构建重定义这些操作。每个ConcreteBuilder包含了创建和装配一个特定产品的所有代码
  (注意:ConcreteBuilder只是提供了使用部件装配产品的操作接口,但不提供具体的装配算法,装配算法在导向器[Director]中定义)。
  这些代码只需要写一次;然后不同的Director可以复用它,以在相同部件集合的基础上构建不同的Product。

  回过头再来看,类图结构中对Director的注释,为什么不是一句builder->BuildPart()就够了,为什么要有这个循环呢?
  BuildPart方法封装了创建Part、并组装到Product中的操作,循环调用调用多次时,可以反复复用BuildPart操作,让目标Product聚合多个Part。
  再进一步:如果Part中可以聚合多个Part,然后递归下去,可以组合成一颗树型结构,这就是Composite了;
  在来理解相关模式中的这句话:“Composite通常是用Builder生成的”,就很容易理解了。

  另外,需要指出的一点。单纯的Builder模式中,“不同Product类型”的组成部件之间,不能进行组合或替换
  譬如上面的两个示例中:组成普通Equipment的普通InputPort、OutputPort、Machine,不允许与组成
  SuperEquipment的SuperInputPort、SuperOutputPort、SuperMachine进行组合创建新的Equipment;
  人的头身臂腿,与奥特曼的头身臂腿,或者汽车人的头身臂腿,三者之间的部件不能兼容或替换。
  这一点GOF在DP中并没有说明,但是在他们给出的两个例子中,充分体现了这一点:RTF的三个转换器,
  ASCIIConvert只负责组合ASCIICharactar,TeXConverter之负责组合自身格式的部件(Charactor、FontChange、Paragraph),
  TextWidgetConverter同理;因此不可能出现由TextWidget格式的Charactor和TeX格式的Paragraph组合而成的Text。
  GOF的另一个Builder模式的应用示例是StandardMazeBuilder与CountingMazeBuilder;GOF在介绍创建型模式时,
  前后多次用到Wall/BombedWall、Room/RoomWithABomb,为什么这里GOF偏偏不用BombedMazeBuilder,
  而别出心裁搞出个CountingMazeBuilder;他们很巧妙地回避了部件替换问题。
  假如允许“不同Product类型”的组成部件之间进行组合或替换,譬如我们允许将奥特曼的头与变形金刚的头进行互换,
  或者允许将机器人的身体替换的人的身体来构建出钢铁侠,或者使用其他组合来构建金刚狼,我们该怎么办呢?
  这个问题已经超出了Builder模式的范畴,先留着。

  Builder模式和AbstractFactory模式比较像,都是用于创建复杂对象。主要的区别在于,Builder模式着重于一步一步构造一个复杂对象,
  而AbstractFactory模式更倾向于多个系列产品的构造。Builder模式在最后一步返回产品,而AbstractFactory模式的产品则是立即返回的。

 

posted @ 2014-03-12 19:50  JarekTan  阅读(256)  评论(0编辑  收藏  举报