一、背景
對於有多個可選參數的類,我們一般通過什麼辦法傳遞參數呢?這裡提供了三種辦法:
①. 重疊構造器模式
②. JavaBeans模式
③. Builder構建器模式
下面我們來分析一下以上三種方法的優勢及弊端。
二、重疊構造器模式
重疊構造器模式中第一個構造器中只有必要參數,第二個構造器有一個可選參數,第三個構造器中有兩個可選參數,依次類推,最後一個構造器中包含所有可選參數。這種方案可行,但是有較大缺陷。
缺點:當有很多可選參數的時候,客戶端代碼很難編寫,並難以閱讀,如果客戶端不小心顛倒了其中兩個參數的順序,編譯器也不會報錯,但是程序在運行時會出現錯誤的行為。
/* * 構造器模式 */ public class NutritionFacts1 { private int a1; // 必須 private int a2; // 必須 private int a3; // 可選 private int a4; // 可選 public NutritionFacts1(int a1, int a2) { this(a1, a2, 0); } public NutritionFacts1(int a1, int a2, int a3) { this(a1, a2, 0, 0); } public NutritionFacts1(int a1, int a2, int a3, int a4) { this.a1 = a1; this.a2 = a2; this.a3 = a3; this.a4 = a4; } public int getA1() { return a1; } public void setA1(int a1) { this.a1 = a1; } public int getA2() { return a2; } public void setA2(int a2) { this.a2 = a2; } public int getA3() { return a3; } public void setA3(int a3) { this.a3 = a3; } public int getA4() { return a4; } public void setA4(int a4) { this.a4 = a4; } public String toString() { return a1 + "-" + a2 + "-" + a3 + "-" + a4; } public static void main(String[] args) { NutritionFacts1 nf = new NutritionFacts1(1, 2, 3, 4); System.out.println(nf); } }
查看本欄目
三、JavaBeans模式
JavaBeans模式中調用一個無參的構造器來創建對象,然後調用setter方法來設置每個必要的參數。
缺點:構造過程被分到了幾個調用中,在構造過程中JavaBean可能處於不一致的狀態,同時在構造過程中JavaBean可能處於不一致的狀態,需要付出額外努力確保線程安全。
/* * JavaBeans模式 */ public class NutritionFacts2 { private int a1 = -1; private int a2 = -1; private int a3; private int a4; public NutritionFacts2() { } public int getA1() { return a1; } public void setA1(int a1) { this.a1 = a1; } public int getA2() { return a2; } public void setA2(int a2) { this.a2 = a2; } public int getA3() { return a3; } public void setA3(int a3) { this.a3 = a3; } public int getA4() { return a4; } public void setA4(int a4) { this.a4 = a4; } public static void main(String[] args) { NutritionFacts2 nf = new NutritionFacts2(); nf.setA1(1); nf.setA2(2); nf.setA3(3); nf.setA4(4); } }
四、Builder構建器模式
最優方案:既能保證像構造器模式那樣的安全性,也能保證像JavaBeans模式那麼好的可讀性
①. 不直接生成想要的對象,而是讓客戶端利用所有必要的參數調用構造器,得到一個builder對象。
②. 客戶端在builder對象上調用類似setter的方法來設置每個相關的可選參數。
③. 客戶端調用無參的build方法來生成不可變的對象,這個builder是它構建的類的靜態成員類。
/* * Builder模式 */ public class NutritionFacts3 { private int a1; // 必須 private int a2; // 必須 private int a3; // 可選 private int a4; // 可選 public static class Builder { private int a1; // 必須 private int a2; // 必須 private int a3 = 0; // 可選 private int a4 = 0; // 可選 public Builder(int a1, int a2) { this.a1 = a1; this.a2 = a2; } public Builder setA3(int a3) { this.a3 = a3; return this; } public Builder setA4(int a4) { this.a4 = a4; return this; } public NutritionFacts3 build() { return new NutritionFacts3(this); } } private NutritionFacts3(Builder builder) { this.a1 = builder.a1; this.a2 = builder.a2; this.a3 = builder.a3; this.a4 = builder.a4; } public String toString() { return a1 + "-" + a2 + "-" + a3 + "-" + a4; } public static void main(String[] args) { NutritionFacts3 nf = new NutritionFacts3.Builder(1, 2).build(); System.out.println(nf); } }
作者:csdn博客 zdp072