遇到多个构造器参数时要考虑用构建器:
- 静态工厂和构造器有个共同的局限性,它们都不能很好的扩展到大量的可选参数。
- JavaBeans模式,在这种模式下调用一个无参数构造器来创建对象,然后调用setter方法来设置每个必要的参数,以及每个 相关的可选参数。
- Builder模式,既能保证向重载构造器模式那样安全,也能保证像JavaBeans模式那么好的可读性。
静态内部类模式:
package thread;
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 {
// Required parameters
private final int servingSize;
private final int servings;
// Optional parameters - initialized to default values
private int calories = 0;
private int fat = 0;
private int carbohydrate = 0;
private int sodium = 0;
public Builder(int servingSize, int servings) {
this.servingSize = servingSize;
this.servings = servings;
}
public Builder calories(int val) {
calories = val;
return this;
}
public Builder fat(int val) {
fat = val;
return this;
}
public Builder carbohydrate(int val) {
carbohydrate = val;
return this;
}
public Builder sodium(int val) {
sodium = val;
return this;
}
public NutritionFacts build() {
return new NutritionFacts(this);
}
}
private NutritionFacts(Builder builder) {
this.servingSize = builder.servingSize;
this.servings = builder.servings;
this.calories = builder.calories;
this.fat = builder.fat;
this.sodium = builder.sodium;
this.carbohydrate = builder.carbohydrate;
}
}
注意:NutritionFacts是不可变的,所有的默认参数都是单独放在一个地方。builder的setter方法返回builder本身,以便可以把调用链接起来。下面是客户端代码:
new NutritionFacts.Builder(20, 6).calories(1).fat(2).carbohydrate(2).sodium(2).build();