首页 > 代码库 > 设计模式【4】:生成器【创建对象】

设计模式【4】:生成器【创建对象】

生成器设计模式是针对实例化复杂对象的设计的。

定义:生成器模式也称为建造者模式。生成器模式的意图在于将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示(GoF)。在软件设计中,有时候面临着一个非常复杂的对象的创建工作。这个复杂的对象通常可以分成几个较小的部分,由各个子对象组合出这个复杂对象的过程相对来说比较稳定,但是子对象的创建过程各不相同并且可能面临变化。根据OOD中的OCP原则,应该对这些子对象的创建过程进行变化封装。

一. 生成器模式简介
  这就是生成器模式的思路。定义一个抽象的建造者的角色(Builder),规定所有具体的建造者都应该具有的功能——这些功能就是如何创建复杂对象的某个特定部分(子对象),声明创建接口,而具体如何创建子对象由具体的创建者(ConcreteBuilder)实现。再定义一个指导者的角色,它把创建者作为工具,知道如何使用这个工具来创建复杂对象。这样,客户在需要创建这个复杂对象的时候,只需要给指导者一个具体的创建者就可以了。至于具体创建者如何创建子对象的细节以及这些子对象之间的差异,不是指导者,也不是客户关心的。

UML结构图:


二. 参与者

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


协作

客户创建Director对象,并用它所想要的Builder对象进行配置。
一旦产品部件被生成,导向器就会通知生成器。
生成器处理导向器的请求,并将部件添加到该产品中。


适用性

1.         当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式时
2.         当构造过程必须允许被构造的对象有不同的表示时。

为何使用?

       是为了将构建复杂对象的过程和它的部件解耦.注意: 是解耦过程和部件.
因为一个复杂的对象,不但有很多大量组成部分,如汽车,有很多部件:车轮 方向盘 发动机还有各种小零件等等,部件很多,但远不止这些,如何将这些部件装配成一辆汽车,这个装配过程也很复杂(需要很好的组装技术),Builder模式就是为了将部件和组装过程分开.

如何使用?

首先假设一个复杂对象是由多个部件组成的,Builder模式是把复杂对象的创建和部件的创建分别开来,分别用Builder类和Director类来表示.
首先,需要一个接口,它定义如何创建复杂对象的各个部件,只是处理部件,不涉及产品的逻辑:

[java] view plaincopy
  1. public interface Builder {  
  2.   
  3.   //创建部件A  比如创建汽车车轮  
  4.   void buildPartA();   
  5.   //创建部件B 比如创建汽车方向盘  
  6.   void buildPartB();   
  7.   //创建部件C 比如创建汽车发动机  
  8.   void buildPartC();   
  9.   
  10.   //返回最后组装成品结果 (返回最后装配好的汽车)  
  11.   //成品的组装过程不在这里进行,而是转移到下面的Director类中进行.  
  12.   //从而实现了解耦过程和部件  
  13.   Product getResult();  
  14.   
  15. }  

用Director构建最后的复杂对象,而在上面Builder接口中封装的是如何创建一个个部件(复杂对象是由这些部件组成的),也就是说Director的内容是如何将部件最后组装成成品,处理部件与产品的关系:

[java] view plaincopy
  1. public class Director {  
  2.   
  3.   private Builder builder;  
  4.   
  5.   public Director( Builder builder ) {   
  6.     this.builder = builder;   
  7.   }   
  8.   // 将部件partA partB partC最后组成复杂对象  
  9.   //这里是将车轮 方向盘和发动机组装成汽车的过程  
  10.   public void construct() {   
  11.     builder.buildPartA();  
  12.     builder.buildPartB();  
  13.     builder.buildPartC();  
  14.   
  15.   }  
  16.   
  17. }  

Builder的具体实现ConcreteBuilder:
通过具体完成接口Builder来构建或装配产品的部件;
定义并明确它所要创建的是什么具体东西;
提供一个可以重新获取产品的接口:

[java] view plaincopy
  1. public class ConcreteBuilder implements Builder {  
  2.   
  3.   Part partA, partB, partC;   
  4.   public void buildPartA() {  
  5.     //这里是具体如何构建partA的代码  
  6.   
  7.   };   
  8.   public void buildPartB() {   
  9.     //这里是具体如何构建partB的代码  
  10.   };   
  11.    public void buildPartC() {   
  12.     //这里是具体如何构建partB的代码  
  13.   };   
  14.    public Product getResult() {   
  15.     //返回最后组装成品结果  
  16.   };   
  17.   
  18. }  

我们看看如何调用Builder模式:

[java] view plaincopy
  1. ConcreteBuilder builder = new ConcreteBuilder();  
  2. Director director = new Director( builder );   
  3.   
  4. director.construct();   
  5. Product product = builder.getResult();   



生成器模式实例

  

当客户需要一个产品时,把需要的参数传递个导向器,导向器根据传递的参数调用具体的生成器,具体的生成器通过一系列的操作(getAnimal()通过调用其它的接口方法实现)最会返回一个产品。
Bridge模式的优点:
1.         它使你可以改变一个产品的内部表示,Builder对象提供给导向器一个构造产品的抽象接口,该接口使得生成器可以隐藏这个产品的表示和内部结构,他同时也隐藏了该产品是如何装配的,因为产品时通过抽象接口构造的(注:本例子把接口的实现放在具体类中了),你在改变该产品的内部表示时所要做的只是定义一个新的生成器。
2.         他将构造代码和表示代码分开,这有点类似于模板模式。所不同的是模版模式最终是完成复杂的工作,而生成器的目的是要生成一个复杂的对象。
3.         他使得你对构造过程进行更加精细的控制。Builder模式是在导向者的控制下一步一步构造产品的,仅当该产品完成时,导向者才从生成器中取回产品。因此Builder模式能更好的反映产品的构造过程,使你可以更精细的控制构建过程,从而能更精细的控制所的产品的内部结构。


对比