比如要创建这么一个对象:
创建对象的方式:
1.可伸缩构造方法,但是参数过多会变得难以阅读和维护,读者不知道这些值是什么意思,并且必须仔细地去数参数才能找到答案。一长串相同类型的参数可能会导致一些细微的 bug。如果客户端不小心写反了两个这样的参数,编译器并不会报错,但是程序在运行时会出现错误行为。
// Telescoping constructor pattern - does not scale well!public class NutritionFacts {private final int servingSize; // (mL) requiredprivate final int servings; // (per container) requiredprivate final int calories; // (per serving) optionalprivate final int fat; // (g/serving) optionalprivate final int sodium; // (mg/serving) optionalprivate final int carbohydrate; // (g/serving) optionalpublic 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) {this.servingSize = servingSize;this.servings = servings;this.calories = calories;this.fat = fat;this.sodium = sodium;this.carbohydrate = carbohydrate;}}
2.通过java bean模式,在构造过程中 JavaBean 可能处于不一致的状态
public class NutritionFacts {// Parameters initialized to default values (if any)private int servingSize = -1; // Required; no default valueprivate int servings = -1; // Required; no default valueprivate int calories = 0;private int fat = 0;private int sodium = 0;private int carbohydrate = 0;public NutritionFacts() { }// Setterspublic void setServingSize(int val) { servingSize = val; }public void setServings(int val) { servings = val; }public void setCalories(int val) { calories = val; }public void setFat(int val) { fat = val; }public void setSodium(int val) { sodium = val; }public void setCarbohydrate(int val) { carbohydrate = val; }}NutritionFacts cocaCola = new NutritionFacts();cocaCola.setServingSize(240);cocaCola.setServings(8);cocaCola.setCalories(100);cocaCola.setSodium(35);cocaCola.setCarbohydrate(27);
3.通过建造者模式,即能保证像重叠构造器的安全性,也能保证像 JavaBeans 模式那么好的可读性
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 parametersprivate final int servingSize;private final int servings;// Optional parameters - initialized to default valuesprivate 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 sodium(int val) {sodium = val;return this;}public Builder carbohydrate(int val) {carbohydrate = val;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 cocaCola = new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build();
