Java學習筆記(二)の遇到多個構造器參數時要考慮用構建器 – JAVA編程語言程序開發技術文章

靜態工廠和構造器有個共同的局限性:它們都不能很好地擴展到大量的可選參數。考慮用一個類表示包裝食品外面顯示的營養成分標簽。這些標簽中有幾個域是必須的:每份的含量、每罐的含量以及每份的卡路裡,還有超過20哥可選域:總脂肪量、飽和脂肪量、轉化脂肪、膽固醇、鈉等等。大多數產品在某幾個可選域中都會有非零的值。

對於這樣的類,應該用哪種構造器或者靜態方法來編寫呢?

1.重疊構造器模式

[java] // Telescoping constructor pattern – does not scale well!    
 
public class NutritionFacts { 
    private final int servingSize;   // (mL)            required  
    private final int servings;      // (per container) required  
    private final int calories;      //                 optional  
    private final int fat;           // (g)             optional  
    private final int sodium;        // (mg)            optional  
    private final int carbohydrate;  // (g)             optional  
 
    public NutritionFacts(int servingSize, int servings) { 
        this(servingSize, servings, 0); 
    } 
 
    public NutritionFacts(int servingSize, int servings, 
            int calories) { 
        this(servingSize, servings, calories, 0); 
    } 
 
    public NutritionFacts(int servingSize, int servings, 
            int calories, int fat) { 
        this(servingSize, servings, calories, fat, 0); 
    } 
 
    public NutritionFacts(int servingSize, int servings, 
            int calories, int fat, int sodium) { 
        this(servingSize, servings, calories, fat, sodium, 0); 
    } 
 
    public NutritionFacts(int servingSize, int servings, 
           int calories, int fat, int sodium, int carbohydrate) { 
        this.servingSize  = servingSize; 
        this.servings     = servings; 
        this.calories     = calories; 
        this.fat          = fat; 
        this.sodium       = sodium; 
        this.carbohydrate = carbohydrate; 
    } 
 
    public static void main(String[] args) { 
        NutritionFacts cocaCola = 
            new NutritionFacts(240, 8, 100, 0, 35, 27); 
    } 

// Telescoping constructor pattern – does not scale well! 

public class NutritionFacts {
    private final int servingSize;   // (mL)            required
    private final int servings;      // (per container) required
    private final int calories;      //                 optional
    private final int fat;           // (g)             optional
    private final int sodium;        // (mg)            optional
    private final int carbohydrate;  // (g)             optional

    public NutritionFacts(int servingSize, int servings) {
        this(servingSize, servings, 0);
    }

    public NutritionFacts(int servingSize, int servings,
            int calories) {
        this(servingSize, servings, calories, 0);
    }

    public NutritionFacts(int servingSize, int servings,
            int calories, int fat) {
        this(servingSize, servings, calories, fat, 0);
    }

    public NutritionFacts(int servingSize, int servings,
            int calories, int fat, int sodium) {
        this(servingSize, servings, calories, fat, sodium, 0);
    }

    public NutritionFacts(int servingSize, int servings,
           int calories, int fat, int sodium, int carbohydrate) {
        this.servingSize  = servingSize;
        this.servings     = servings;
        this.calories     = calories;
        this.fat          = fat;
        this.sodium       = sodium;
        this.carbohydrate = carbohydrate;
    }

    public static void main(String[] args) {
        NutritionFacts cocaCola =
            new NutritionFacts(240, 8, 100, 0, 35, 27);
    }
}2.JavaBeans模式

[java] // Telescoping constructor pattern – does not scale well!    
 
public class NutritionFacts { 
    private final int servingSize;   // (mL)            required  
    private final int servings;      // (per container) required  
    private final int calories;      //                 optional  
    private final int fat;           // (g)             optional  
    private final int sodium;        // (mg)            optional  
    private final int carbohydrate;  // (g)             optional  
 
    public NutritionFacts(int servingSize, int servings) { 
        this(servingSize, servings, 0); 
    } 
 
    public NutritionFacts(int servingSize, int servings, 
            int calories) { 
        this(servingSize, servings, calories, 0); 
    } 
 
    public NutritionFacts(int servingSize, int servings, 
            int calories, int fat) { 
        this(servingSize, servings, calories, fat, 0); 
    } 
 
    public NutritionFacts(int servingSize, int servings, 
            int calories, int fat, int sodium) { 
        this(servingSize, servings, calories, fat, sodium, 0); 
    } 
 
    public NutritionFacts(int servingSize, int servings, 
           int calories, int fat, int sodium, int carbohydrate) { 
        this.servingSize  = servingSize; 
        this.servings     = servings; 
        this.calories     = calories; 
        this.fat          = fat; 
        this.sodium       = sodium; 
        this.carbohydrate = carbohydrate; 
    } 
 
    public static void main(String[] args) { 
        NutritionFacts cocaCola = 
            new NutritionFacts(240, 8, 100, 0, 35, 27); 
    } 

// Telescoping constructor pattern – does not scale well! 

public class NutritionFacts {
    private final int servingSize;   // (mL)            required
    private final int servings;      // (per container) required
    private final int calories;      //                 optional
    private final int fat;           // (g)             optional
    private final int sodium;        // (mg)            optional
    private final int carbohydrate;  // (g)             optional

    public NutritionFacts(int servingSize, int servings) {
        this(servingSize, servings, 0);
    }

    public NutritionFacts(int servingSize, int servings,
            int calories) {
        this(servingSize, servings, calories, 0);
    }

    public NutritionFacts(int servingSize, int servings,
            int calories, int fat) {
        this(servingSize, servings, calories, fat, 0);
    }

    public NutritionFacts(int servingSize, int servings,
            int calories, int fat, int sodium) {
        this(servingSize, servings, calories, fat, sodium, 0);
    }

    public NutritionFacts(int servingSize, int servings,
           int calories, int fat, int sodium, int carbohydrate) {
        this.servingSize  = servingSize;
        this.servings     = servings;
        this.calories     = calories;
        this.fat          = fat;
        this.sodium       = sodium;
        this.carbohydrate = carbohydrate;
    }

    public static void main(String[] args) {
        NutritionFacts cocaCola =
            new NutritionFacts(240, 8, 100, 0, 35, 27);
    }
}3.Builder模式,既能保證安全性,又能保證可讀性。

[java] // Builder Pattern   
 
public class NutritionFacts { 
    private final int servingSize; 
    private final int servings; 
    private final int calories; 
    private final int fat; 
    private final int sodium; 
    private final int carbohydrate; 
 
    public static class Builder { 
        // Required parameters  
        private final int servingSize; 
        private final int servings; 
 
        // Optional parameters – initialized to default values  
        private int calories      = 0; 
        private int fat           = 0; 
        private int carbohydrate  = 0; 
        private int sodium        = 0; 
 
        public Builder(int servingSize, int servings) { 
            this.servingSize = servingSize; 
            this.servings    = servings; 
        } 
 
        public Builder calories(int val) 
            { calories = val;      return this; } 
        public Builder fat(int val) 
            { fat = val;           return this; } 
        public Builder carbohydrate(int val) 
            { carbohydrate = val;  return this; } 
        public Builder sodium(int val) 
            { sodium = val;        return this; } 
 
        public NutritionFacts build() { 
            return new NutritionFacts(this); 
        } 
    } 
 
    private NutritionFacts(Builder builder) { 
        servingSize  = builder.servingSize; 
        servings     = builder.servings; 
        calories     = builder.calories; 
        fat          = builder.fat; 
        sodium       = builder.sodium; 
        carbohydrate = builder.carbohydrate; 
    } 
 
    public static void main(String[] args) { 
        NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8). 
            calories(100).sodium(35).carbohydrate(27).build(); 
    } 

 

摘自  horsttnann的專欄 

發佈留言