一、背景
對於有多個可選參數的類,我們一般通過什麼辦法傳遞參數呢?這裡提供了三種辦法:
①. 重疊構造器模式
②. 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