代码改变世界

创建类模式(三):创建者(Builder)

2016-10-27 13:39  阿诚de窝  阅读(326)  评论(0编辑  收藏  举报

定义

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

和工厂模式的区别

  1. 工厂模式注重的对象创建的结果,而创建者模式注重的对象创建的过程。
  2. 与抽象工厂模式相比, 建造者模式返回一个组装好的完整产品 ,而抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族。
  3. 在抽象工厂模式中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在建造者模式中,客户端可以不直接调用建造者的相关方法,而是通过指挥者类来指导如何生成对象,包括对象的组装过程和建造步骤,它侧重于一步步构造一个复杂对象,返回一个完整的对象。
  4. 如果将抽象工厂模式看成汽车配件生产工厂 ,生产一个产品族的产品,那么建造者模式就是一个汽车组装工厂 ,通过对部件的组装可以返回一辆完整的汽车。

UML

优点

  • 在创建者模式中,客户端不再负责对象的创建与组装,而是把这个对象创建的责任交给其具体的创建者类,把组装的责任交给组装类,客户端只负责对象的调用,从而明确了各个类的职责。

缺点

  • 虽然利用创建者模式可以创建出不同类型的产品,但是如果产品之间的差异巨大,则需要编写多个创建者类才能实现,如果这是结合工厂模式更好。

应用场景

  1. 需要生成的产品对象有复杂的内部结构。
  2. 需要生成的产品对象的属性相互依赖,建造者模式可以强迫生成顺序。
  3. 在对象创建过程中会使用到系统中的一些其他对象,这些对象在产品对象的创建过程中不易得到。

示例

通过创建者创建房子。

Java

  1 import java.util.ArrayList;
  2 
  3 public class Main
  4 {
  5     public static void main(String[] args)
  6     {
  7         Director director=new Director();
  8         
  9         Builder chineseBuilder=new ChineseBuilder();
 10         director.construct(chineseBuilder);
 11         House chineseHouse=chineseBuilder.GetHouse();
 12         chineseHouse.show();
 13         
 14         Builder englandBuilder=new EnglandBuilder();
 15         director.construct(englandBuilder);
 16         House englandHouse=englandBuilder.GetHouse();
 17         englandHouse.show();
 18     }
 19     
 20     /**
 21      * 抽象建造者
 22      */
 23     public static abstract class Builder
 24     {
 25         public abstract void BuildDoor();
 26         public abstract void BuildWall();
 27         public abstract void BuildWindows();
 28         public abstract void BuildHouseCeiling();
 29         public abstract House GetHouse();
 30     }
 31 
 32     /**
 33      * 进行建造的产品
 34      */
 35     public static class House
 36     {
 37         private ArrayList<String> parts = new ArrayList<String>();
 38         
 39         public void add(String str)
 40         {
 41             parts.add(str);
 42         }
 43         
 44         public void show()
 45         {
 46             for(String part : parts)
 47             {
 48                 System.out.println(part);
 49             }
 50             System.out.println("");
 51         }
 52     }
 53 
 54     /**
 55      * 导演类
 56      */
 57     public static class Director
 58     {
 59         public void construct(Builder builder)
 60         {
 61             builder.BuildDoor();
 62             builder.BuildWall();
 63             builder.BuildWindows();
 64             builder.BuildHouseCeiling();
 65         }
 66     }
 67 
 68     /**
 69      * 具体类型的建造者
 70      */
 71     public static class ChineseBuilder extends Builder
 72     {
 73         private House chineseHouse = new House();
 74         
 75         public void BuildDoor()
 76         {
 77             chineseHouse.add("ChineseDoor");
 78         }
 79         
 80         public void BuildWall()
 81         {
 82             chineseHouse.add("ChineseWall");
 83         }
 84         
 85         public void BuildWindows()
 86         {
 87             chineseHouse.add("ChineseWindows");
 88         }
 89         
 90         public void BuildHouseCeiling()
 91         {
 92             chineseHouse.add("ChineseHouserCeiling");
 93         }
 94         
 95         public House GetHouse()
 96         {
 97             return chineseHouse;
 98         }
 99     }
100 
101     /**
102      * 具体类型的建造者
103      */
104     public static class EnglandBuilder extends Builder
105     {
106         private House englandHouse = new House();
107         
108         public void BuildDoor()
109         {
110             englandHouse.add("EnglandDoor");
111         }
112         
113         public void BuildWall()
114         {
115             englandHouse.add("EnglandWall");
116         }
117         
118         public void BuildWindows()
119         {
120             englandHouse.add("EnglandWindows");
121         }
122         
123         public void BuildHouseCeiling()
124         {
125             englandHouse.add("EnglandHouserCeiling");
126         }
127         
128         public House GetHouse()
129         {
130             return englandHouse;
131         }
132     }
133 }
View Code