方法一是采用重疊構(gòu)造器模式跷坝,缺點很明顯砖茸,當參數(shù)很多時隘擎,需要的構(gòu)造器要非常多,而且代碼不易閱讀凉夯。
方法二是采用JavaBeans模式货葬,調(diào)用無參構(gòu)造器來構(gòu)造對象,再通過大量的set方法來設置參數(shù)劲够,解決了方法一的缺點震桶,但是構(gòu)造過程被分到幾個調(diào)用中,構(gòu)造過程中JavaBean可能處于不一致的狀態(tài)征绎,需要額外的努力來確保它的線程安全(解決方法:當對象的構(gòu)造完成蹲姐,不允許在解凍之前使用,通過手動“凍結(jié)”對象人柿,但是比較笨拙)柴墩。
方法三是采用Builder模式的一種形式,保證了安全性和可讀性凫岖。
示例如下:
public class NutritionFacts {
private Integer servingSize;
private Integer servings;
private Integer calories;
private Integer fat;
private Integer sodium;
private Integer carbohydrate;
public static class Builder {
// Required parameters
private Integer servingSize;
private Integer servings;
// Optional parameters
private Integer calories;
private Integer fat = 0; // 添加一個默認值
private Integer carbohydrate;
private Integer sodium;
public Builder(Integer servingSize, Integer servings) {
this.servingSize = servingSize;
this.servings = servings;
}
public Builder calories(Integer calories) {
this.calories = calories;
return this;
}
public Builder fat(Integer fat) {
this.fat = fat;
return this;
}
public Builder carbohydrate(Integer carbohydrate) {
this.carbohydrate = carbohydrate;
return this;
}
public Builder sodium(Integer sodium) {
this.sodium = sodium;
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.carbohydrate = builder.carbohydrate;
this.sodium = builder.sodium;
}
@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 cocaCola = new NutritionFacts.Builder(240, 8)
.calories(100)
.sodium(35)
.carbohydrate(27)
.build();
System.out.println("cocaCola: " + cocaCola);
NutritionFacts pepsiCola = new NutritionFacts.Builder(240, 8)
.calories(100)
.fat(35)
.carbohydrate(27)
.build();
System.out.println("pepsiCola: " + pepsiCola);
}
}
----------------------------------------------------
輸出:
cocaCola: NutritionFacts [servingSize=240, servings=8, calories=100, fat=0, sodium=35, carbohydrate=27]
pepsiCola: NutritionFacts [servingSize=240, servings=8, calories=100, fat=35, sodium=null, carbohydrate=27]
如果使用JDK1.5及以上版本江咳,只要一個泛型就能滿足所有的builder,無論它們在構(gòu)建哪種類型的對象隘截。
// A builder for objects of type T
public interface Builder<T> {
T build();
}
public class NutritionFacts {
private Integer servingSize;
private Integer servings;
private Integer calories;
private Integer fat;
private Integer sodium;
private Integer carbohydrate;
public static class Builder implements com.sun.istack.internal.Builder<NutritionFacts> {
// Required parameters
private Integer servingSize;
private Integer servings;
// Optional parameters
private Integer calories;
private Integer fat = 0; // 添加一個默認值
private Integer carbohydrate;
private Integer sodium;
public Builder(Integer servingSize, Integer servings) {
this.servingSize = servingSize;
this.servings = servings;
}
public Builder calories(Integer calories) {
this.calories = calories;
return this;
}
public Builder fat(Integer fat) {
this.fat = fat;
return this;
}
public Builder carbohydrate(Integer carbohydrate) {
this.carbohydrate = carbohydrate;
return this;
}
public Builder sodium(Integer sodium) {
this.sodium = sodium;
return this;
}
@Override
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.carbohydrate = builder.carbohydrate;
this.sodium = builder.sodium;
}
@Override
public String toString() {
return "NutritionFacts [servingSize=" + servingSize
+ ", servings=" + servings + ", calories=" + calories
+ ", fat=" + fat + ", sodium=" + sodium
+ ", carbohydrate=" + carbohydrate + "]";
}
}
Builder模式也有不足扎阶,為了創(chuàng)建對象汹胃,必須先創(chuàng)建它的構(gòu)建器,在某些十分注重性能的情況下东臀,可能開銷就有問題着饥。Builder模式比重疊構(gòu)造器模式更冗長。