第2条:遇到多个构造器参数时要考虑用构建器
思考:考虑用一个类表示包装食品外显示的营养成分标签。这些标签有几个域是必须的:每份的含量、每罐的含量以及每份的卡路里,还有超过20个可选域:总脂肪量、饱和脂肪量、转化脂肪、胆固醇、钠等等。大多数产品的某几个可选域中都会有几个非零的值。
对于这样的类,应该采用哪种构造器或者静态方法来编写呢?程序员一向习惯用重叠构造器(telescoping constructor)模式,在这种模式下,你提供一个必要的参数构造器,第二个构造器有一个可选参数,第三个构造器有两个可选参数,以此类推,最后一个构造器包含所有的可选参数。下面有个示例,为了简单起见,它只显示四个可选域:
1 public class NutritionFacts { 2 private final int servingSize; //(ml) required 3 private final int servings; //(per container) required 4 private final int calories; // optional 5 private final int fat; //(g) optional 6 private final int sodium; //(mg) optional 7 private final int carbohydrate; //(g) optional 8 public NutritionFacts(int servingsize, int servings) { 9 this(servingsize,servings,0); 10 } 11 public NutritionFacts(int servingsize, int servings, int calories) { 12 this(servingsize,servings,calories,0); 13 } 14 public NutritionFacts(int servingsize, int servings, int calories, int fat) { 15 this(servingsize,servings,calories,fat,0); 16 } 17 public NutritionFacts(int servingsize, int servings, int calories, int fat, int sodium) { 18 this(servingsize,servings,calories,fat,sodium,0); 19 } 20 public NutritionFacts(int servingsize, int servings, int calories, int fat, int sodium, int carbohydrate) { 21 super(); 22 this.servingSize = servingsize; 23 this.servings = servings; 24 this.calories = calories; 25 this.fat = fat; 26 this.sodium = sodium; 27 this.carbohydrate = carbohydrate; 28 } 29 }
方法的弊端:这个构造器通常需要许多你本不想设置的参数,但还是不得不为它们传递值。并且随着参数数目的增加,难以控制。
方法的总结:重叠构造器模式可行,但是当有许多参数的时候,客户端代码会很难编写,并且仍然较难以阅读。用户无法快速明确的知道参数代表的意思。一串类型相同的参数,输入过程中出错,编译器不会出错,但是程序运行时会出现错误的行为。
第二种实现方法:JavaBeans模式,在这种模式下,调用一个无参构造器来创建对象,然后调用setter方法来设置每个必要的参数,以及每个可选的相关参数:
1 public class NutritionFacts { 2 private int servingSize = -1; 3 private int servings = -1; 4 private int calories = 0; 5 private int fat = 0; 6 private int sodium = 0; 7 private int carbohydrate = 0; 8 public NutritionFacts() {} 9 //Setters 10 public void setServingSize(int servingSize) { 11 this.servingSize = servingSize; 12 } 13 public void setServings(int servings) { 14 this.servings = servings; 15 } 16 public void setCalories(int calories) { 17 this.calories = calories; 18 } 19 public void setFat(int fat) { 20 this.fat = fat; 21 } 22 public void setSodium(int sodium) { 23 this.sodium = sodium; 24 } 25 public void setCarbohydrate(int carbohydrate) { 26 this.carbohydrate = carbohydrate; 27 }; 28 }
这种模式弥补了重叠构造器模式的不足,就是创建实例很容易,这样产生的代码读起来也很容易:
NutritionFacts cocaCola = new NutritionFacts(); cocaCola.setServingSize(240); cocaCola.setServings(8); cocaCola.setCalories(100); cocaCola.setFat(35); cocaCola.setCarbohydrate(27);
原文:https://www.cnblogs.com/remote/p/10051172.html