模块化生产将产品的各个部分分别打造,最终组装起来得到一个完整的产品。同时,相同的一堆零件在组装过程中的顺序或用量不同时,可以得到不同的产品。
相比其他创建型设计模式,工厂模式强调如何生产一个对象,而建造者模式强调顺序。数量不同,组合生成的对象也就会可能产生不同的对象。
1.建造者模式组成
建造者模式通常由如下几部分构成,
部分 | 说明 |
---|---|
(抽象)建造者(builder) | Builder负责定义用于生成实例对象的接口 |
具体建造者(ConcreteBuilder) | 该角色负责实现Builder定义的接口的实现类。针对不同的逻辑,具体化产品各部分的创建,并在构建完成后提供产品实例 |
监工(Director) | 监工复杂使用Builder定义的接口生成实例对象。只负责保证对象各部分完整创建或安装某种顺序创建。即只负责指挥如何创建,具体交给Builder |
产品(Product) | 要创建的复杂对象 |
使用者(Client) | 使用创建者模式的人 |
以建造一间屋子为例,假设地基、混凝土结构、屋顶等都是单独创建并在最后组装。
2.代码实现
- 实现产品类
public class Product {
private String ground;
private String cement;
private String roof;
public Product() {
}
public String getGround() {
return this.ground;
}
public void setGround(String ground) {
this.ground = ground;
}
public String getCement() {
return this.cement;
}
public void setCement(String cement) {
this.cement = cement;
}
public String getRoof() {
return this.roof;
}
public void setRoof(String roof) {
this.roof = roof;
}
}
- 实现Builder
public interface Builder {
// 一般而言,有多少零件就会有多少个创建方法
void buildGround();
void buildCement();
void buildRoof();
// 返回产品类
Product buildProduct();
}
- 实现ConcreteBuilder
对Builder接口进行实现,
public class ConcreteBuilder implements Builder {
private final Product product = new Product();
@Override
public void buildGround() {
System.out.println("build地基");
product.setGround("build地基");
}
@Override
public void buildCement() {
System.out.println("build水泥");
product.setGround("build水泥");
}
@Override
public void buildRoof() {
System.out.println("build房顶");
product.setGround("build房顶");
}
@Override
public Product buildProduct() {
System.out.println("建造完毕");
return this.product;
}
}
- 实现监工类
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public Product construct() {
// 构建顺序 水泥 -> 地基 -> 楼顶
builder.buildCement();
builder.buildGround();
builder.buildRoof();
return builder.buildProduct();
}
}
- Client进行调用
public class Main {
public static void main(String[] args) {
Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
director.construct();
}
}
3.优缺点总结
- 封装性:客户端无需指定产品内部的组合细节,只需要考虑生成的对象。如
Main
类并不知道Builder
实现类中具体的制作过程,只是调用了Director
类的construct方法完成产品制作 - 易于拓展:可以实现其余的
Builder
接口的实现类,并在其中定义不同的制作过程。上面的代码中建造的是一个一层的平房。如果想造更大的房子,可以定义另一个实现类,多调用几次 buildCement 方法就可以建造更高的楼。
Builder
实现类之间彼此独立,具有良好的拓展性,符合开闭原则 - 便于控制细节:由于建造者彼此独立,可以对具体建造过程逐步细化,不会对其他模块产生影响
4.与工厂方法比较
- 建造者模式关注的是零件类型和装配顺序。同为创建型模式,注重点不同
- 另外工厂模式只有一个建造方法,而建造者模式有多个建造零部件的方法并且强调建造顺序,而工厂模式没有顺序的概念