Item 2 (Builder), Effective Java

15922 ワード

コンストラクション関数に多くのパラメータがある場合は、コンストラクタを考慮します。


コンストラクション関数を使用して作成する場合は、パラメータが多い場合にも使用できます。


Telescotting Constructor Pattern(レイヤジェネレータアレイ単位)


次のコード
  • に従って、異なる作成者を作成します.
  • ただし、初期化する必要があるフィールドはすべての作成者に含まれます.
  • public class Test{
    	private final String fieldA;
        private String fieldB;
        private String fieldC;
        private String fieldD;
        
        public Test(String fieldA){ ... }
        public Test(String fieldA, String fieldB){ ... }
        public Test(String fieldA, String fieldB, String fieldC){ ... }
        public Test(String fieldA, String fieldB, String fieldC, String fieldD){ ... }
    }
  • このモードの問題は、同じデータ型に複数のパラメータがある場合、パラメータ値で並べ替えるとコンパイラが気づかず、実行時に問題が発生することです.
  • public class Test{
        private String fieldA;
        private String fieldB;
        
        public Test(String fieldA, String fieldB){ ... }
    }
    
    Test test = new Test(fieldB, fieldA); // 두 인자의 순서가 바뀜 하지만 컴파일 오류는 없음

    JavaBeans Pattern(JavaBeansモード)


    オブジェクトを作成したら、
  • パラメータを含まずにsetterに値を変更します.
  • このメソッドでは、オブジェクトを作成するために多くのメソッドを呼び出す必要があります.
  • さらに、オブジェクトが完全に作成される前に、コンシステンシはクラッシュ状態にある.
  • public class Test{
    	private String fieldA;
        private String fieldB;
        
        public Test(){ ... };
        
        public void setFieldA(String fieldA){ ... }
        public void setFieldB(String fieldB){ ... }
    }
    
    Test test = new Test();
    test.setFieldA("");
    test.setFieldB("");

    Builder Patternは最高の代替製品です


    オブジェクト内にclassを作成します。

  • オブジェクト内にBuilderというクラスを作成します.
  • ジェネレータは、自身を返すようにパラメータ値を受信する.
  • は、最終的にbuildanメソッドを使用してオブジェクトを返します.
  • メソッドでオブジェクトを機械的に生成します.
  • 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 {
            private final int servingSize;
            private final int servings;
    
            private int calories = 0;
            private int fat = 0;
            private int sodium = 0;
            private int carbohydrate = 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 sodium(int val) {
                sodium = val;
                return this;
            }
    
            public Builder carbohydrate(int val) {
                carbohydrate = val;
                return this;
            }
        }
    
        public NutritionFacts(Builder builder) {
            this.servingSize = builder.servingSize;
            this.servings = builder.servings;
            this.calories = builder.calories;
            this.fat = builder.fat;
            this.sodium = builder.sodium;
            this.carbohydrate = builder.carbohydrate;
        }
    }

    この2つの方法の利点が結合している。

  • ジェネレータを作成すると、オブジェクトの必須パラメータに基づいて作成されます.( Telescoping Constructor Pattern )
  • 必要なパラメータの値
  • のみを受け入れて保存します.( JavaBeans Pattern )
  • 注意点

  • ジェネレータPatternを使用すると、パラメータの少ない作成者よりもコードが長くなる可能性があります.
  • 以降にコンストラクション関数として処理する必要があるパラメータが多くなる可能性がある場合に使用することが望ましい.