阎宏博士的《JAVA与模式》一书中开头是这样描述建造者(Builder)模式的:
建造者模式是对象的创建模式。建造者模式可以将一个产品的内部表象(internal representation)与产品的生产过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。
产品的内部表象
一个产品对象的属性是产品的零件。这些零件可能不是对象,又叫做产品的内部表象(internal representation)。不同的产品可以有不同的内部表象即不同的零件。建造者模式通过导演者对象和具体建造者对象建造所有的零件,从而建造出完整的产品对象。建造者模式结构见下图:
最终产品Product只有两个属性即part1和part2,相应的建造方法有buildPart1和buildPart2。
涉及到的4个角色:
抽象建造者(Builder)角色:给出一个抽象接口来规范产品对象的各个属性对应的建造方法。属性数量与建造方法数量相等。
具体建造者(ConcreteBuilder)角色:产品类数量与具体建造者类数量相等。任务:1 实现抽象建造者接口,给出具体的建造方法。2 产品对象属性建造后,返回一个产品实例。
导演(Director)角色:通过具体建造者角色来创建产品对象。将客户端创建产品对象的请求划分成各个属性的建造请求,再将这些请求发送给具体建造者角色。
产品(Product)角色:一个系统可以有多个产品类,它们不一定有共同的接口,因为它们可以是不相关的。
产品类Product:
1 public class Product { 2 /** 3 * 定义一些关于产品的操作 4 */ 5 private String part1; 6 private String part2; 7 public String getPart1() { 8 return part1; 9 } 10 public void setPart1(String part1) { 11 this.part1 = part1; 12 } 13 public String getPart2() { 14 return part2; 15 } 16 public void setPart2(String part2) { 17 this.part2 = part2; 18 } 19 }
抽象建造者类Builder:
1 public interface Builder { 2 public void buildPart1(); 3 public void buildPart2(); 4 public Product retrieveResult(); 5 }
具体建造者类ConcreteBuilder:
1 public class ConcreteBuilder implements Builder { 2 3 private Product product = new Product(); 4 /** 5 * 产品零件建造方法1 6 */ 7 @Override 8 public void buildPart1() { 9 //构建产品的第一个零件 10 product.setPart1("编号:9527"); 11 } 12 /** 13 * 产品零件建造方法2 14 */ 15 @Override 16 public void buildPart2() { 17 //构建产品的第二个零件 18 product.setPart2("名称:XXX"); 19 } 20 /** 21 * 产品返还方法 22 */ 23 @Override 24 public Product retrieveResult() { 25 return product; 26 } 27 28 }
导演者类Director
1 public class Director { 2 /** 3 * 持有当前需要使用的建造器对象 4 */ 5 private Builder builder; 6 /** 7 * 构造方法,传入建造器对象 8 * @param builder 建造器对象 9 */ 10 public Director(Builder builder){ 11 this.builder = builder; 12 } 13 /** 14 * 产品构造方法,负责调用各个零件建造方法 15 */ 16 public void construct(){ 17 builder.buildPart1(); 18 builder.buildPart2(); 19 } 20 }
客户端:
1 public class Client { 2 public static void main(String[]args){ 3 Builder builder = new ConcreteBuilder(); 4 Director director = new Director(builder); 5 director.construct(); 6 Product product = builder.retrieveResult(); 7 System.out.println(product.getPart1()); 8 System.out.println(product.getPart2()); 9 } 10 }
时序图:
客户端负责创建导演和具体建造者对象。然后,客户端把具体建造者对象交给导演对象,导演通过具体建造者对象创建产品对象。最后,客户端获取了产品实例。客户端负责创建具体建造者对象,使导演对象可以使用多个具体建造者对象中的任何一个。
建造者模式分成两个重要部分:定义建造方法的Builder接口和负责装配零件的导演类。重心在于分离产品构建方法和零件构建方法,有利于通过组合来构造不同的产品对象。
适用场景:
1 产品对象的一个属性必须在另一个属性被赋值之后才可以被赋值。
2 要用到的其他对象在对象创建过程中不易得到。
参考资料