「設計Pattern」ビルダーアレイ(Builder Pattern)


ビルド・ペトン
  • 複雑なオブジェクトを作成する方法を定義するクラスと、どのように表現するかを定義するクラスを分離し、異なる表現でも作成できる同じプロセスを提供します.
  • ビルダーモードは、作成するオブジェクトがより多くのオプション属性を持つ必要がある場合により大きな役割を果たします.
  • 生成モードの所属.ビルダーモード
  • 作成モード=抽象インスタンス作成プロセスのためのモード
  • 生成モードが属するモードは、オブジェクトを作成および合成する方法またはオブジェクトの表現方法をシステムから分離する.
  • システムは継承よりも複合手法を用いる方向に発展することが重要である.
  • 2つの主要な話題.

  • 作成モードは、システムがどのタイプを使用するかに関する情報をカプセル化します.

  • 作成モードは、これらのクラスのインスタンスがどのように作成され、どのように結合されているかを完全に区別します.
  • つまり、アレイを作成することで、何を生成するか、誰が作成するか、どのように作成するか、いつ作成するかを決定する柔軟性が得られます.
    概念的にもう一度見る.
    オプションのメンバー変数や不連続状態値の処理が必要な問題を解決します.
    ❌ファクトリモード、抽象ファクトリモードで作成するクラスの属性値が多い場合、以下の問題があります.
  • クライアントプログラムからファクトリクラスに大量のパラメータを渡すと,タイプ,順序などの管理が困難になり,エラーの確率が増加する.
  • の場合、不要なパラメータについては、空の値を工場クラスに1つずつ渡す必要があります.
  • を生成する必要があるサブクラスが重く複雑になるにつれて、工場クラスも複雑になる.
  • ААААААААААА
    必要な値に対して、関数を構築します.
    オプションの値については、次の方法を使用します.
    stey-by-stepで値を入力し、build()メソッドで最終的にインスタンスを返します.
    👋 よく使われるパターンの1つです.
    Retrofit、OkHttpなどの有名なオープンソースコードもコンストラクタモードを使用しています.
    実施方法

  • コンストラクタクラスをStatic Nestedクラスとして作成します.
    この場合、通常、作成するクラス名の後にBuilderが追加されます.
    ex. Computer class -> ComputerBuilder

  • コンストラクタクラスの作成者はpublicであり、必要な値は作成者のパラメータとして受信されます.

  • オプションの値では、各プロパティにメソッドが提供されます.重要なのは、メソッドの戻り値がコンストラクタオブジェクト自体である必要があります.

  • 最後に、コンストラクタクラスでコンストラクション()メソッドを定義し、クライアント・プログラムに最終的に生成された成果物を提供する必要があります.
    これにより、build()のみでオブジェクトによって作成されたクラスを提供する作成者はprivateとして定義する必要があります.
  • ComputerBuilder Example
    public class Computer {
    	
        //required parameters
        private String HDD;
        private String RAM;
    	
        //optional parameters
        private boolean isGraphicsCardEnabled;
        private boolean isBluetoothEnabled;
    	
     
        public String getHDD() {
            return HDD;
        }
     
        public String getRAM() {
            return RAM;
        }
     
        public boolean isGraphicsCardEnabled() {
            return isGraphicsCardEnabled;
        }
     
        public boolean isBluetoothEnabled() {
            return isBluetoothEnabled;
        }
    	
        // 여기 🛑
        // 클래스의 생성자는 private 하게. 구현 방법 4번 ✅
        private Computer(ComputerBuilder builder) {
            this.HDD=builder.HDD;
            this.RAM=builder.RAM;
            this.isGraphicsCardEnabled=builder.isGraphicsCardEnabled;
            this.isBluetoothEnabled=builder.isBluetoothEnabled;
        }
    	
        //Builder Class
        // static이 포인트. 구현 방법 1번 ✅
        // 빌더 클래스 생성자는 public으로 한다. 구현 방법 2번 ✅
        public static class ComputerBuilder{
     
            // required parameters        
            private String HDD;
            private String RAM;
     
            // optional parameters
            private boolean isGraphicsCardEnabled;
            private boolean isBluetoothEnabled;
    		
            // 필수값들은 파라미터로 받는다. 구현 방법 2번 ✅
            public ComputerBuilder(String hdd, String ram){
                this.HDD=hdd;
                this.RAM=ram;
            }
     
            public ComputerBuilder setGraphicsCardEnabled(boolean isGraphicsCardEnabled) {
                this.isGraphicsCardEnabled = isGraphicsCardEnabled;
                return this;
            }
     
     		// 옵션 값들은 속상마다 메소드로 제공한다.
            // 리턴값이 빌더 객체 자신이다. 구현 방법 3번 ✅
            public ComputerBuilder setBluetoothEnabled(boolean isBluetoothEnabled) {
                this.isBluetoothEnabled = isBluetoothEnabled;
                return this;
            }
    		       
            public Computer build(){
                return new Computer(this);
            }
     
        }
     
    }
    ポイント
    共通ジェネレータとコンピュータクラスがないのはgetterメソッドのみで、setterメソッドはありません.(赤を上に表示)🛑探してみます.公共の作成者ではありません.)
    したがって、コンピュータオブジェクトを取得するには、コンピュータジェネレータクラスしか使用できません.
    どのように使いますか.
    public class TestBuilderPattern {
     
        public static void main(String[] args) {
        	
            // Computer 객체를 얻기 위해 ComputerBuilder를 이용한다.
            Computer comp = new Computer.ComputerBuilder("500 GB", "2 GB") //필수값은 파라미터로 넣어줌.
                    .setBluetoothEnabled(true) //옵션값은 메서드로 제공.
                    .setGraphicsCardEnabled(true)
                    .build();
        }
     
    }