Builder Pattern


Builder Pattern

  • オブジェクトを作成するときによく使用されるパターン.
  • 長所

  • は、必要なデータのみを設定できます.
  • の柔軟性が得られます.
  • コードの読み取り可能性を向上させます.
  • の変更の可能性を減らします.
  • User user = User.build()
    			.id("aaa")
                .name("aaa")
                .password("password")
                .build()

    Effective Javaのビルダーモード

  • オブジェクトの簡潔化の作成
  • Telescopeコンストラクション関数モード(階層単位コンストラクション関数モード)
  • JavaBeansモード->ポイント積層ジェネレータモードの代替案
  • ビルダーモード(ビルダーモード)->JavaBeansモードの代替案
  • オブジェクトの柔軟な作成
  • builderインタフェースを使用して、複数のbuilderを使用します.
  • Telescoppingコンストラクタモード(ポイントコンストラクタモード)

  • に必要な作成者を生成します(必要なパラメータを受信します).
  • 1のオプションパラメータの作成者を追加します.
  • 2個のオプションパラメータのジェネレータを追加します.
  • 繰り返し
  • のすべてのオプションパラメータの作成者を追加します.
  • public class Employee {
    
    	private final String name;  // 필수 인자
        private final String salary; // 선택적 인자
        private final String email;  // 선택적 인자
        
        // 필수 인자를 받는 생성자 
        public Employee(String name){
        	this(name,"연봉 비공개", "이메일 비공개");
            }
        
        // 1개의 선택적 인자를 받는 생성자
        public Employee(String name, String salary){
        	this(name,salary,"이메일 비공개");
        }
        // 모든 인자를 다 받는 생성자
         public Employee(String name, String salary, String email){
        	this.name = name;
            this.salary = salary;
            this.email = email;
            } 

    長所

  • は、入力パラメータに使用することができる.
  • 短所


    他のコンストラクション関数を呼び出すコンストラクション関数が多いため、パラメータを追加するとコードを変更するのは難しい.
  • コードは毒性に欠けている.
  • パラメータの意味を理解するのは難しい.
  • // parameter가 무엇을 의미하는지 파악하기 어려움.
    Order newOrder = new Order(1,200, 5000, 1,2);

    JavaBeans Pattern

  • setterを使用してコードを読み取り可能にします.
  • Order newOrder = new Order();
    newOrder.setId(1);
    newOrder.setQuentity(200);
    newOrder.setPrice(5000);
    newOrder.setProduct(1);
    newOrder.setStore(2);

    長所

  • パラメータの識別が容易です.
  • は、複数のコンストラクション関数を必要としない.
  • 短所

  • オブジェクトが一致しません.
  • 1コールでは、オブジェクトの作成が完了することはありません.一度に作成するのではなく、作成したオブジェクトに値を追加します.
  • setterがある場合は、可変クラスを作成できません.
  • Builder Pattern(Effective Javaスタイル)

    public class Product {
    	private final String name;
        private final int quentity;
        private final int price;
        private final String store;
        private final String option;
        
        public static class Builder {
        // Required parameters(필수 인자)
        private final String name;
        private fianl int quentity;
        private final int price;
        
        // Optional Parameters - initialized to default values
        private String store = "None";
        private String option = "None";
        
        public Builder(String name, int quentity, int price){
        	this.name = name;
            this.quentity = quentity;
            this.price = price;
        }
        public Builder store(String store){
        	store = store;
            return this; // 이렇게하면 .으로 체인을 이어갈 수 있음.
        }
        public Builder option(String option){
        	option = option;
            return this;
        }
        
        public Product build() {
        	return new Product(this);
        }
      }
      
      private Product(Builder builder){
      		name = builder.name;
            quentity = builder.quentity;
            price = builder.price;
            store = builder.store;
            option = builder.option;
       }
       }

    オブジェクト1の作成

    Product.bbuilder builder = new Product.builder('chip', 100, 2000);
    builder.store('market');
    builder.option('crispy');
    Product prod = budiler.build();

    オブジェクト2の作成

    Product prod = new Product.Builder('chip', 100, 2000)
    						      .store('market')
                                  .option('crispy')
                                  .build(); // build()가 객체 생성해서 return

    長所

  • パラメータの意味は分かりやすい.
  • setterがなければ、変更できないオブジェクトを作成できます.
  • ->オブジェクトの一貫性を一度に作成できます.
  • build()関数に無効な値が入力されていることを確認できます.
  • Lombokの@Builder

  • クラスまたはコンストラクション関数に@Builderコメントを追加することで、この機能Javaと同様のコンストラクタモードを作成できます.
  • クラスで@Builder

    @Builder
    public class Product {
    	private final String name;
        private final int quentity;
        private final int price;
        private final String store;
        private final String option;
        }

    Constructorで@Builder

    public class Product {
    	private final String name;
        private final int quentity;
        private final int price;
        private final String store;
        private final String option;
        }
    @Builder
     private Product(String name, int quentity, int price, String store, String option){
      		this.name = name;
            this.quentity = quentity;
            this.price = price;
            this.store = store;
            this.option = option;

    オブジェクト1の作成

    Product.ProductBuilder builder = Product.builder();
    builder.name('chip');
    builder.quentity(100);
    Product prod = builder.build();

    オブジェクト2の作成

    Product prod = Product.builder()
    					  .name('chip')
                          .quentity(100)
                          .build();

    クラス宣言での@Builderの使用を禁止

  • @Builderをclassに掛けるのは、@AllArgConstructorを掛けるのと同じです.できるだけ自分で作ったジェネレータに掛けます.
  • Builder Interface

  • インタフェースを作成すると、builder classによって実装されます.
  • public interface Builder<T> {
    	public T build();
    }
    Ref:
    https://johngrib.github.io/wiki/pattern/builder/
    https://mangkyu.tistory.com/163