程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Effective Java (2) 遇到多個構造器參數時要考慮用構建器

Effective Java (2) 遇到多個構造器參數時要考慮用構建器

編輯:關於JAVA

一、背景

對於有多個可選參數的類,我們一般通過什麼辦法傳遞參數呢?這裡提供了三種辦法:

①. 重疊構造器模式

②. 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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved