创建模式之—Builder

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

Builder模式是一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象的类型和内容就可以构建它们.用户不知道内部的具体构建细节.Builder模式是非常类似抽象工厂模式,细微的区别大概只有在反复使用中才能体会到.

为何使用?
是为了将构建复杂对象的过程和它的部件解耦.注意: 是解耦过程和部件.


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


如何使用?
首先假设一个复杂对象是由多个部件组成的,Builder模式是把复杂对象的创建和部件的创建分别开来,分别用Builder类和Director类来表示.


首先,需要一个接口,它定义如何创建复杂对象的各个部件:

public interface Builder {

  //创建部件A  比如创建汽车车轮
  void buildPartA();
  //创建部件B 比如创建汽车方向盘
  void buildPartB();
  //创建部件C 比如创建汽车发动机
  void buildPartC();

  //返回最后组装成品结果 (返回最后装配好的汽车)
  //成品的组装过程不在这里进行,而是转移到下面的Director类中进行.
  //从而实现了解耦过程和部件
  Product getResult();

}


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

public class Director {

  private Builder builder;

  public Director( Builder builder ) {
    this.builder = builder;
  }
  // 将部件partA partB partC最后组成复杂对象
  //这里是将车轮 方向盘和发动机组装成汽车的过程
  public void construct() {
    builder.buildPartA();
    builder.buildPartB();
    builder.buildPartC();

  }

}


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

public class ConcreteBuilder implements Builder {

  Part partA, partB, partC;
  public void buildPartA() {
    //这里是具体如何构建partA的代码

  };
  public void buildPartB() {
    //这里是具体如何构建partB的代码
  };
   public void buildPartC() {
    //这里是具体如何构建partB的代码
  };
   public Product getResult() {
    //返回最后组装成品结果
  };


}


复杂对象:产品Product:


public interface Product { } 

复杂对象的部件:

public interface Part { }



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


ConcreteBuilder builder = new ConcreteBuilder();
Director director = new Director( builder );

director.construct();
Product product = builder.getResult();


Builder模式的应用
在Java实际使用中,我们经常用到"池"(Pool)的概念,当资源提供者无法提供足够的资源,并且这些资源需要被很多用户反复共享时,就需要使用池.

"池"实际是一段内存,当池中有一些复杂的资源的"断肢"(比如数据库的连接池,也许有时一个连接会中断),如果循环再利用这些"断肢",将提高内存使用效率,提高池的性能.修改Builder模式中Director类使之能诊断"断肢"断在哪个部件上,再修复这个部件.
 
 
版本2

建造者模式,属于创建型模式,其目的在于将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
适用情况:
• 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
• 当构造过程必须允许被构造的对象有不同的表示时。

类结构图如下所示

 

 参与者

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

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

实现代码:

  1. package com.visionsky.DesignPattern; 
  2.  
  3. class Product 
  4.     @Override 
  5.     public String toString() { 
  6.         return "Product"; 
  7.     }  
  8.  
  9. interface Builder 
  10.     void BuildPart(); 
  11.  
  12. class ConcreteBuilder implements Builder 
  13.      
  14.     @Override 
  15.     public void BuildPart() { 
  16.         // TODO Auto-generated method stub 
  17.         System.out.println("Building Product's part"); 
  18.     } 
  19.      
  20.     public Product GetResult() 
  21.     { 
  22.         System.out.println("Product's Building has finished"); 
  23.         return new Product(); 
  24.           
  25.     } 
  26.  
  27. class Director 
  28.     public Product Construct(ConcreteBuilder cb) 
  29.     { 
  30.         cb.BuildPart(); 
  31.         return cb.GetResult(); 
  32.     } 
  33.  
  34. public class BuilderDemo { 
  35.  
  36.     /** 
  37.      * @param args 
  38.      */ 
  39.     public static void main(String[] args) { 
  40.         // TODO Auto-generated method stub 
  41.         Director d=new Director(); 
  42.         ConcreteBuilder cb=new ConcreteBuilder(); 
  43.         Product p=d.Construct(cb); 
  44.         System.out.println(p); 
  45.     } 

生活中的例子:
在这里我们以造汽车为例子,汽车是由个很复杂的对象,有很多个子对象组成,如轮胎,引擎,车架等,所以为了造好一辆汽车,其子对象必须具备。
 

  1. package com.visionsky.DesignPattern; 
  2.  
  3.  
  4. class Car{ 
  5.  
  6.     @Override 
  7.     public String toString() { 
  8.         return "汽车产品"; 
  9.     } 
  10.  
  11. interface  IBuilder 
  12.     void BuildWheel(); 
  13.     void BuildCarFrame(); 
  14.     void BuildEngine();  
  15.  
  16. class CarBuilder implements IBuilder 
  17.  
  18.     private Car car=new Car(); 
  19.     @Override 
  20.     public void BuildCarFrame() { 
  21.         // TODO Auto-generated method stub 
  22.         System.out.println("建造汽车框架"); 
  23.     } 
  24.  
  25.     @Override 
  26.     public void BuildEngine() { 
  27.         // TODO Auto-generated method stub 
  28.         System.out.println("建造汽车轮子"); 
  29.     } 
  30.  
  31.     @Override 
  32.     public void BuildWheel() { 
  33.         // TODO Auto-generated method stub 
  34.         System.out.println("建造汽车引擎"); 
  35.     } 
  36.      
  37.     public Car CarBuildOver() 
  38.     { 
  39.         System.out.println("汽车组装完毕"); 
  40.         return car; 
  41.     } 
  42.  
  43. class CarDirector 
  44.      
  45.     public Car BuildCar(CarBuilder cb) 
  46.     { 
  47.         cb.BuildCarFrame(); 
  48.         cb.BuildEngine(); 
  49.         cb.BuildWheel(); 
  50.         return cb.CarBuildOver(); 
  51.     } 
  52.  
  53. public class BuliderDemoInLife { 
  54.  
  55.     /** 
  56.      * @param args 
  57.      */ 
  58.     public static void main(String[] args) { 
  59.         // TODO Auto-generated method stub 
  60.         CarDirector cd=new CarDirector(); 
  61.         Car c=cd.BuildCar(new CarBuilder()); 
  62.         System.out.println(c); 
  63.     } 

 

posted on 2012-11-25 11:39  YangJin  阅读(232)  评论(0编辑  收藏  举报