第2条:遇到多个构造器参数时要考虑用构造器
静态工厂和构造器有个共同的局限性:它们都不能很好地扩展到大量的可选参数。
那么有大量可选参数时该如何构造对象呢?
第一种方法:重叠构造器(telescope constructer)当你想要创建实例的时候,就利用参数列表最短的构造器,其它的值会赋默认值。
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 NutritionFacts(int servingSize, int servings) {
this(servingSize,servings,0);
}
public NutritionFacts(int servingSize, int servings, int calories) {
this(servingSize, servings,calories,0);
}
public NutritionFacts(int servingSize, int servings, int calories, int fat) {
this(servingSize,servings,calories,fat,0);
}
public NutritionFacts(int servingSize, int servings, int calories, int fat,
int sodium) {
this(servingSize,servings,calories,fat,sodium,0);
}
public NutritionFacts(int servingSize, int servings, int calories, int fat,
int sodium, int carbohydrate) {
super();
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = fat;
this.sodium = sodium;
this.carbohydrate = carbohydrate;
}
}
缺点:如果参数多了的话,就失去了控制。
第2中:JavaBean模式。
public class NutritionFacts {
private int servingSize=-1;
private int servings=-1;
private int calories=0;
private int fat=0;
private int sodium=0;
private int carbohydrate=0;
public int getServingSize() {
return servingSize;
}
public void setServingSize(int servingSize) {
this.servingSize = servingSize;
}
public int getServings() {
return servings;
}
public void setServings(int servings) {
this.servings = servings;
}
public int getCalories() {
return calories;
}
public void setCalories(int calories) {
this.calories = calories;
}
public int getFat() {
return fat;
}
public void setFat(int fat) {
this.fat = fat;
}
public int getSodium() {
return sodium;
}
public void setSodium(int sodium) {
this.sodium = sodium;
}
public int getCarbohydrate() {
return carbohydrate;
}
public void setCarbohydrate(int carbohydrate) {
this.carbohydrate = carbohydrate;
}
}
/***客服端代码**/
public static void main(String[] args) {
NutritionFacts cocaCola=new NutritionFacts();
cocaCola.setServingSize(240);
cocaCola.setServings(8);
cocaCola.setCalories(100);
}
缺点:构造过程被分到了几个调用中,在构造过程中JavaBean可能处于不一致的状态。
第3种 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;
/**
* 静态内部类
* @author weix
*
*/
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 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);
}
}
public 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;
}
/****客户端****/
public static void main(String[] args) {
NutritionFacts cocaCola=new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build();
}
}
缺点:为了创建对象,必须先创建他的构造器,在十分注重性能的情况下,可能成问题。比重叠构造器模式更加冗长,因此他只在有很多参数的时候才使用4个或者更多。