欧美vvv,亚洲第一成人在线,亚洲成人欧美日韩在线观看,日本猛少妇猛色XXXXX猛叫

新聞資訊

    前言

    上一篇記錄了用靜態工廠 VS 構造器,本片繼續記錄書中的提到的其它的方式。

    闡述

    在第二節開篇,作者提出自己的見解。

    靜態工廠和構造器有個共同的局限性,它們都不能很好的拓展到大量的可選參數。

    本想使用自己在練習中的例子,但書中給的實例實在是優秀ug10后處理構造器下載,所以下文大部分引用書中的案例。比如,用一個類表示包裝食品的營養成分標簽,其中有幾個域是必須的:每份的含量、每罐的含量以及每份的卡路里。還有幾個可選域:總脂肪量、飽和脂肪量、轉化脂肪、膽固醇、鈉等等。大多數產品在幾個可選域中都會有非零的值。

    重疊構造器

    對于選用哪種方式來創建,按照我們常規的方式一般就會采用 重疊構造器 模式,這種模式中,提供的第一個構造器只需包含必要的參數,第二個構造器有一個可選參數,第二個構造器有兩個可選參數,以此類推,最后一個構造器包含所有的可選參數。以下是一個只顯示四個可選域的實例:

    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);
    }
    

    其中的某個參數可能是我們不想設置的,但是不得不為它們傳遞值。這個例子中,我們給 fat 傳遞了一個值為 0。如果僅僅是 6 個參數,還在我們的可控范圍ug10后處理構造器下載,問題是隨著功能和參數的增加,很快就會失去控制。

    簡而言之,重疊構造器模式可行,但是當有許多參數的時候,客戶端的代碼會很難編寫,并且難以閱讀。

    如果我們想知道具體的值是什么意思,必須仔細地去讀參數的注釋。如果是一長串類型相同的參數必然會導致一些微妙的錯誤,如果不小心顛倒了其中兩個參數的順序,編譯器并不會報錯,但是最終的結果可能會出現錯誤的行為。

    這種情況下,還有第二種替代方式。

    模式

    這種模式下,先調用一個無參構造器來創建對象,然后通過調用 set 方法來設置每個必要的參數和可選參數,例如:

    public class NutritionFacts {
        // Parameters initialized to default values (if any)
        private int servingSize = -1; 
        private int servings = -1; 
        private int calories = 0;
        private int fat = 0;
        private int sodium = 0;
        private int carbohydrate = 0;
        public NutritionFacts() {}
      // set function
        public void setServingSize(int val) { servingSize = val; }
        public void setServings(int val) { servings = val; }
        public void setCalories(int val) { calories = val; }
        public void setFat(int val) { fat = val; }
        public void setSodium(int val) { sodium = val; }
        public void setCarbohydrate(int val) { carbohydrate = val; }
    }
    

    這種模式彌補了重疊構造器的不足,創建實例很容易,這樣的代碼可讀性也非常高:

    public static void main(String[] args) {
        NutritionFacts cocaCola = new NutritionFacts();
        cocaCola.setServingSize(240);
        cocaCola.setServings(8);
        cocaCola.setCalories(100);
        cocaCola.setSodium(35);
        cocaCola.setCarbohydrate(27);
    }
    

    美中不足的是, 模式自身有一些缺點:

    類在構造過程中被分到了幾個調用中,在構造過程中 可能處于不一致的狀態

    類無法僅僅通過檢驗構造器參數的有效性來保證一致。

    模式使得把類做成不可變的可能性不復存在(后邊單獨更新),需要付出額外的努力確保它的線程安全

    針對這種情況,書中給出了第三種替代方式。

    建造者模式 它既能保證像重疊構造器模式那樣的安全性,也能保證像 模式那么好的可讀性

    示例:

    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;
        }
    }
    

    注意 是不可變的,所有的默認參數都單獨放在一個地方, 的設值方法返回 本身,以便把調用鏈接起來,得到一個**流式的 API。**下面是調用示例:

    public static void main(String[] args) {
        NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8)
                    .calories(100).sodium(35).carbohydrate(27).build();
    }
    

    這樣的客戶端代碼很容易編寫,更為重要的是易于閱讀, 模式模擬了明確命名的可選參數。

    總結

    非常喜歡的書中摘錄:

    雖然本書中的規則不會百分之百地適用于任何時刻和任何場合,但是,它們確實體現了絕大多數情況下的最佳編程實踐。你不應該盲目的遵循這些規則,但偶爾有了充分的理由之后,可以去打破這些規則。同大多數學科一樣,學習編程藝術首先要學會基本的規則,然后才能知道什么時候去打破它。

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有