定义:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
本质:
分离整体构建算法和部件构造。
优点:
1、松散耦合,生成器模式可以用同一个构建算法构建出表现上完全不同的产品, 实现产品构建和产品表现上的分离。生成器模式正是把产品构建的过程独立出来, 使它和具体产品的表现松散耦合, 从而使得构建算法可以复用, 而具体产品表现也可以灵活地、方便地扩展和切换。
2、可以很容易地改变产品的内部表示,在生成器模式中, 由于Builder对象只是提供接口给Director使用,那么具体的部件创建和装配方式是被Builder接口隐藏了的, Director并不知道这些具体的实现细节。这样一来,要想改变产品的内部表示,只需要切换Builder的具体实现即可, 不用管Director, 因此变得很容易。
3、更好的复用性,生成器模式很好地实现了构建算法和具体产品实现的分离。这样一来, 使得构建产品的算法可以复用。同样的道理, 具体产品的实现也可以复用, 同一个产品的实现, 可以配合不同的构建算法使用。
不用设计模式示例:
public class WithoutBuilderPatternDemo {
public static void main(String[] args) {
// 构造这个复杂的product对象
Product product = new Product();
// 设置field1属性
System.out.println("在设置field1之前进行复杂的校验逻辑");
product.setField1("值1");
// 设置field2属性
System.out.println("在设置field2之前进行复杂的数据格式转化逻辑");
product.setField2("值2");
// 设置field3属性
System.out.println("在设置field3之前进行复杂的数据处理逻辑,跟其他对象的数据进行关联");
product.setField3("值3");
/**
* 存在问题:
* 多字段的复杂对象的构建,会导致代码堆积在一起
*/
}
public static class Product {
private String field1;
private String field2;
private String field3;
public String getField1() {
return field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
public String getField2() {
return field2;
}
public void setField2(String field2) {
this.field2 = field2;
}
public String getField3() {
return field3;
}
public void setField3(String field3) {
this.field3 = field3;
}
}
}
使用设计模式示例:
public class BuilderPatternDemo {
public static void main(String[] args) {
Product product = new ConcreteBuilder()
.field1("值1")
.field2("值2")
.field3("值3")
.create();
System.out.println(product);
}
public static class Product {
private String field1;
private String field2;
private String field3;
public String getField1() {
return field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
public String getField2() {
return field2;
}
public void setField2(String field2) {
this.field2 = field2;
}
public String getField3() {
return field3;
}
public void setField3(String field3) {
this.field3 = field3;
}
@Override
public String toString() {
return "Product [field1=" + field1 + ", field2=" + field2 + ", field3=" + field3 + "]";
}
}
public interface Builder {
Builder field1(String value);
Builder field2(String value);
Builder field3(String value);
Product create();
}
public static class ConcreteBuilder implements Builder {
private Product product = new Product();
@Override
public Builder field1(String value) {
System.out.println("在设置field1之前进行复杂的校验逻辑");
product.setField1(value);
return this;
}
@Override
public Builder field2(String value) {
System.out.println("在设置field2之前进行复杂的数据格式转化逻辑");
product.setField2(value);
return this;
}
@Override
public Builder field3(String value) {
System.out.println("在设置field3之前进行复杂的数据处理逻辑,跟其他对象的数据进行关联");
product.setField3(value);
return this;
}
@Override
public Product create() {
return product;
}
}
}
何时选用:
1、如果创建对象的算法,应该独立于该对象的组成部分以及它们的装配方式时。
2、如果同一个构建过程有着不同的表示时。
相关模式:
1、建造者模式和工厂方法模式
这两个模式可以组合使用。
建造者模式的Builder 实现中,通常需要选择具体的部件实现。一个可行的方案就是实现成为工厂方法, 通过工厂方法来获取具体的部件对象,然后再进行部件的装配。
2、建造者模式和抽象工厂模式
这两个模式既相似又有区别,也可以组合使用。
抽象工厂桢式的主要目的是创建产品簇,这个产品簇里面的单个产品就相当于是构成一个复杂对象的部件对象,抽象工厂对象创建完成后就立即返回整个产品簇;而生成器模式的主要目的是按照构造算法,一步一步来构建一个复杂的产品对象,通常要等到整个构建过程结束以后,才会得到最终的产品对象。
事实上,这两个模式是可以组合使用的。在建造者模式的Builder 实现中,需要创建各个部件对象,而这些部件对象是有关联的,通常是构成一个复杂对象的部件对象。也就是说, Builder 实现中,需要获取构成一个复杂对象的产品簇,那自然就可以使用抽象工厂模式来实现。这样一来,由抽象工厂模式负责了部件对象的创建, Builder 实现里面则主要负责产品对象整体的构建了。
2、建造者模式和模板方法模式
模板方法模式主要是用来定义算法的骨架,把算法中某些步骤延迟到子类中实现。再想想建造者模式,Director 用来定义整体的构建算法,把算法中某些涉及到具体部件对象的创建。