當類別的構造器參數超過 3~4 個時,傳統的「重疊構造器」或「JavaBeans 模式」都會暴露明顯缺陷:前者導致程式碼難以閱讀與維護,後者破壞不可變性並引發線程安全隱患。Builder 模式 能夠優雅地解決這兩難,兼顧可讀性、不可變性與擴展性。
public class NutritionFacts {
private final int one;
private final int two;
private final int three;
public NutritionFacts(int one, int two, int three) {
this.one = one; this.two = two; this.three = three;
}
public NutritionFacts(int one) { this(one, 0, 0); }
public NutritionFacts(int one, int two) { this(one, two, 0); }
}
// 調用時易混淆參數順序
NutritionFacts facts = new NutritionFacts(0, 0, 0);
缺點:參數一多,構造器呈指數級增長;調用端無法從參數名稱推斷語義,極易傳錯順序。
public class NutritionFacts {
private final int one;
private final int two;
private final int three;
private NutritionFacts(Builder builder) {
this.one = builder.one;
this.two = builder.two;
this.three = builder.three;
}
public static class Builder {
private int one = 0;
private int two = 0;
private int three = 0;
public Builder one(int val) { this.one = val; return this; }
public Builder two(int val) { this.two = val; return this; }
public Builder three(int val) { this.three = val; return this; }
public NutritionFacts build() { return new NutritionFacts(this); }
}
}
// 鏈式調用,語義清晰
NutritionFacts facts = new NutritionFacts.Builder()
.one(10).two(20).three(30)
.build();
final,構建完成後狀態凍結,天然線程安全。build() 中集中檢查參數合法性,拋出異常。若使用 Lombok,僅需在類上標註 @Builder 即可自動生成上述樣板代碼,進一步提升開發效率。