c++设计模式系列----builder模式

看了好几处关于builder模式的书和博客,总感觉不是很清楚,感觉不少书上的说的也不是很准确。最后还是看回圣经《设计模式》。看了好久终于感觉明白了一点了。

意图:

builder模式提出的目的就是为了解决将一个复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不的表示的问题。

我们来看一个例子:

    假设我们要画一些人,例如游戏里面的各类人。一般情况下,人有头,手,腿。但是在游戏里面,人可能没有手,也可能不止两只手。即所谓的三头六臂。如下:

                                               

    那么,在这种情况下应该怎么去生产这些人?

    一开始可能会用这个思路:抽象出一个人的基类,然后不同的人继承自这个基类得到一系列的子类。

   这个方法有很多缺点:

                 1、首先很明显的一点是:不同类型的人差别极大,因为人不是都相同的手相同的腿等,以至于很难抽象出共同点。所以抽象出一个基类本身就不现实。

                 2、利用这种通过继承产生不同人的方法会造成子类的泛滥,比如每多一只手就要多一个子类,造成代码的可拓展性问题,管理问题等。

那么就要用到下面说的builder模式。

builder模式的适用性

 在以下情况使用builder模式
  ? 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
  ? 当构造过程必须允许被构造的对象有不同的表示时。

我们注意,builder模式有两个要注意的点,一个是创建复杂对象算法独立于对象的组成部分以及它们的装配方式。一个是被构造的对象有不同的表示。但我们不能被“复杂对象”所误导,并不是说将复杂对象进行封装就是builder模式了。

我们先来看看模式的结构图:

                                       

其中各部分的作用为:

? Builder:
      为创建一个Product对象的各个部件指定抽象接口。
? ConcreteBuilder
  实现Builder的接口以构造和装配该产品的各个部件。
  定义并明确它所创建的表示。
  提供一个检索产品的接口。
? Director
  构造一个使用Builder接口的对象。
?Product
  表示被构造的复杂对象。ConcreteBuilder 创建该产品的内部表示并定义它的装配过程。
  包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

也就是说,导向器决定构造一个product的算法,比如构造一个人,导向器就决定他的构造顺序:

          1、addHead();   2、addArm();    3、addArm();    4、addArm();   5、addLeg();    6、addLeg();

然后导向器通过调用builder的接口来实现具体构造。这样就实现了创建复杂对象算法和对象的组成部分以及它们的装配方式的分离。

也就是说,builder模式要得到Product并不是通过concreteBuilder一步得到的,它是通过在导向器Director所列出的方法顺序下一步步进行构造得到。并在最后一步后得到一个最终的产品。

我们来看看Director和ConcreteBuilder的协作过程:

                                                             

其中getResult()方法是得到构造好的实例对象。

 

使用builder模式的效果如下:

1、Builder对象提供给导向器的抽象接口的具体实现是在Builder内部,那么在改变接口内部的具体实现的时候就不会对导向器使用接口产生影响。它隐藏了产品是如何装配的。另外,因为Builder的抽象接口是一定的,那么你在改变产品的内部结构的时候只需要定义一个新的生成器CuncreteBuilder。然后使用这个生成器去装配产品即可。

2、它将构造代码和表示代码分开,builder模式通过封装一个复杂对象的创建和表示方式提高了对象的模块性。客户不需要知道定义产品内部的结构的类的所有信息。这些类是不出现在builder接口中的。每个ConcerteBuilder包含了创建和装配一个特定产品的所有代码。这些代码只需要写一次,然后不同的Director可以复用它以在相同的部件集合的基础上构作不同的Product。

3、它使你可对构造过程进行更精细的控制。Builder模式与一下子就生成产品的创建型模式不同,他是在Director的控制下一步步构造产品。仅当产品构造完成后才从生成器取回它。因此Builder接口相比其他创建型模式能更好地反应产品构造过程。这使你能更精细地控制构建过程,从而能更精细地控制所得产品的内部结构。

那么根据上述画出开始时的问题的builder模式的解决方案的结构图如下:

                   

根据图就不难写出代码了。  

值得注意的是,1、产品Product没有抽象类 通常情况下,由具体生成器生成的产品,它们的表示相差很大,以至于给不同的产品以公共父类没有什么。

                    2、在Builder中缺省的方法为空。在C++中,生成方法故意不声明为纯虚函数,而是把它们定义为空方法,这使得客户可以只重定义他们所感兴趣的操作。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。