如果一个类构造器的参数大于四个就要考虑使用构造器来构建类了。它可以使参数更加灵活,扩展性更好并且可以减少一些参数位置写错的情况。
可采用Builder模式的一种形式,不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器(或静态工厂)
得到一个builder对象。然后客户端在builder对象上调用类似setter的方法,来设置每个相关的可选参数。最后,客户端调用无参的build方法来生成不可变的对象。这个builder是它构建的类的静态成员类。
示例:
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;
}
public Builder calories(int calories) {
this.calories = calories;
return this;
}
public Builder fat(int fat) {
this.fat = fat;
return this;
}
public Builder sodium(int sodium) {
this.sodium = sodium;
return this;
}
public Builder carbohydrate(int carbohydrate) {
this.carbohydrate = carbohydrate;
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;
}
@Override
public String toString() {
return "NutritionFacts{" +
"servingSize=" + servingSize +
", servings=" + servings +
", calories=" + calories +
", fat=" + fat +
", sodium=" + sodium +
", carbohydrate=" + carbohydrate +
'}';
}
}
测试:
public class test {
public static void main(String[] args) {
NutritionFacts.Builder builder = new NutritionFacts.Builder(1, 2);
NutritionFacts nutritionFacts = builder.calories(3)
.carbohydrate(4)
.fat(5)
.sodium(6)
.build();
System.out.println(nutritionFacts.toString());
}
}
如果类的构造器或者静态工厂中具有多个参数,设计这种类时,Builder模式就是种不错的选择,特别是当大多数参数都是可选的时候。与使用传统的重叠构造器的模式相比,使用Builder模式的客户端代码更易于阅读和编写,构建器也比JavaBeans更加安全。
参考:《Effective Java》