如何构造有大量可选参数的对象?
重叠构造器:可行,但构造函数太多,代码很难编写,切难以阅读。
javaBeans模式(调用一个无参构造器创建对象,调用setter方法设置每个参数):弥补重叠构造器的不足,但是构造时会产生不一致的状态(一个只设置了A属性,另一个只设置了B属性,不能确定必选参数都设置了),造成调试困难;并且把类变成可变的,设置一个属性后,还能再设置一遍来改变原属性。
Java构建器:不直接生成想要的对象,利用必要的参数调用构造器,得到builder对象,在builder对象上调用类似setter方法,设置每个可选参数,最后,调用无参的build方法生成不可变的对象,这个build是它构建的类的静态成员类。
public class NutritionFacts {//营养事实
//必选的
private final int servingSize;
private final int servings;
//可选的
private final int calories;
private final int fat;
private final int sodium;
private final int carbohydrate;
public static class Builder{
private final int servingSize;
private final int servings;
private int calories=0;
private int fat=0;
private int sodium=0;
private int carbohydrate=0;
/*
* 不直接生成想要的对象,利用必要的参数调用构造器
*/
public Builder(int servingSize,int servings){
this.servingSize=servingSize;
this.servings=servings;
}
/*
* 调用类似setter方法,设置每个可选参数
*/
public Builder calories(int cal){
calories=cal;
return this;
}
public Builder fat(int fa){
fat=fa;
return this;
}
public Builder sodium(int so){
sodium=so;
return this;
}
public Builder carbohydrate(int car){
carbohydrate=car;
return this;
}
/*
* 生成不可变对象
*/
public NutritionFacts build(){
return new NutritionFacts(this);
}
}
private NutritionFacts(Builder builder){
servingSize=builder.servingSize;
servings=builder.servings;
calories=builder.calories;
fat=builder.fat;
sodium=builder.sodium;
carbohydrate=builder.carbohydrate;
}
}
调用方法:
NutritionFacts nur=new NutritionFacts.Builder(7,12).calories(5).fat(9).sodium(23).carbohydrate(88).build();