没有使用模式
package com.zhss.designpattern.builder;
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;
}
}
}
使用模式
package com.zhss.designpattern.builder;
public class BuilderPatternDemo {
public static void main(String[] args) {
Director director = new Director(new ConcreteBuilder());
Product product = director.build("值1", "值2", "值3");
System.out.println(product);
// 好处1:通过builder接口将复杂构建步骤拆分成了多个部分,代码逻辑清晰,维护性和扩展性都很好
// 好处2:将对象构建的过程,封装在了director里面,director来基于builder进行构建,构建逻辑修改,不需要修改很多地方
// 好处3:相对于工厂,有一个很好的抽象设计,director和builder
}
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 {
void field1(String value);
void field2(String value);
void field3(String value);
Product create();
}
public static class ConcreteBuilder implements Builder {
private Product product = new Product();
public void field1(String value) {
System.out.println("在设置field1之前进行复杂的校验逻辑");
product.setField1(value);
}
public void field2(String value) {
System.out.println("在设置field2之前进行复杂的数据格式转化逻辑");
product.setField2(value);
}
public void field3(String value) {
System.out.println("在设置field3之前进行复杂的数据处理逻辑,跟其他对象的数据进行关联");
product.setField3(value);
}
public Product create() {
return product;
}
}
/**
* director是面向builder的接口,来编程的
* director可以复杂控制构建的一个步骤,具体的每个步骤的逻辑封装在具体的builder类中
* 如果我们此时要更换一整套的构建逻辑,可以再搞一个新的builder类就可以了
* 但是我们的整个构建步骤是没有任何改变的
*
* 如果整个构建步骤变化了,但是对构建的逻辑是没有影响的
*
* @author zhonghuashishan
*
*/
public static class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public Product build(String field1, String field2, String field3) {
builder.field1(field1);
builder.field2(field2);
builder.field3(field3);
return builder.create();
}
}
}
优化后的模式
package com.zhss.designpattern.builder;
public class OptimizedBuilderPatternDemo {
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();
public Builder field1(String value) {
System.out.println("在设置field1之前进行复杂的校验逻辑");
product.setField1(value);
return this;
}
public Builder field2(String value) {
System.out.println("在设置field2之前进行复杂的数据格式转化逻辑");
product.setField2(value);
return this;
}
public Builder field3(String value) {
System.out.println("在设置field3之前进行复杂的数据处理逻辑,跟其他对象的数据进行关联");
product.setField3(value);
return this;
}
public Product create() {
return product;
}
}
}
总结
好处:
- 通过builder接口将复杂构建步骤拆分成了多个部分,代码逻辑清晰,维护性和扩展性都很好
- 将对象构建的过程,封装在了director里面,director来基于builder进行构建,构建逻辑修改,不需要修改很多地方
- 相对于工厂,有一个很好的抽象设计,director和builder