建造模式是对象的创建模式。建造模式可以将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同内部表象的产品对象。
产品的内部表象
一个产品常有不同的组成成分作为产品的零件,这些零件有可能是对象,也有可能不是对象,它们通常又叫做产品的内部表象(internal representation)。不同的产品可以有不同的内部表象,也就是不同的零件。使用建造模式可以使客户端不需要知道所生成的产品对象有哪些零件,每个产品的对应零件彼此有何不同,是怎么建造出来的,以及怎样组成产品。
建造模式的结构
为方便读者了解建造模式的结构,下面给出一个示意性的实现:
在这个示例里,最终产品Product只有两个零件,即Part1和Part2。相应的建造方法也有两个:buildPart1()和buildPart2()。同时可以看出本模式涉及到四个角色,它们分别是:
- 抽象建造者(Builder)角色:给出一个抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此接口独立于程序的商业逻辑。模式中直接创建产品对象的是具体建造者(ConcreteBuilder)角色。具体建造者类必须实现这个接口所要求的两种方法:一种是建造方法,比如本例子中的builderPart1()和builderPart2();另一种是结果返还方法,即本例子中的retrieveResult()。一般来说,产品所包含的零件数目与建造方法的数目相符。换言之,有多少个零件,就有多少相应的建造方法。
- 具体建造者(Concrete Builder)角色:担任这个角色的是与应用程序紧密相关的一些类,它们在应用程序调用下创建产品的实例。这个角色要完成的任务包括:实现抽象建造者Builder所声明的接口,给出一步一步地完成创建产品实例的操作。在建造过程完成后,提供产品实例。
- 导演者(Director)角色:担任这个角色的类调用具体建造者角色以创建产品对象。应当指出的是,导演者角色并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者角色。
- 产品(Product)角色:是需要建造的复杂对象。一般来说,一个系统中会有多于一个的产品类,而且这些产品类并不一定有共同的接口,而完全可以是不相关联的。
源代码
模式中Director类的源代码:
package com.javapatterns.builder;
public class Director {
private Builder builder;
/**
* 产品构造方法,负责调用各个零件建造方法
*/
public void construct() {
builder = new ConcreteBuilder();
builder.builderPart1();
builder.builderPart2();
builder.retrieveResult();
//continue with other code
}
}
package com.javapatterns.builder;
public abstract class Builder {
/**
* 产品零件建造方法
*/
public abstract void buildPart1();
/**
* 产品零件建造方法
*/
public abstract void builderPart2();
/**
* 产品返还方法
*/
public abstract Product retrieveResult();
}
具体建造者ConcreteBuilder1的源代码:
package com.javapatterns.builder;
public class ConcreteBuilder1 extends Builder {
private Product product = new Product1();
/**
* 产品返还方法
*/
public Product retrieveResult() {
return product;
}
/**
* 产品零件建造方法
*/
public void buildPart1() {
//build the first part of the product
}
/**
* 产品零件建造方法
*/
public void builderPart2() {
//build the second part of the product
}
}