[책리뷰/Effective Java] 객체 생성과 파괴

OCTOBER 04, 2020

아이템2) 생성자에 매개변수가 많다면 빌더를 고려하라

생성자와 static factory method 의 똑같은 단점은 매개변수가 많을 때 적절히 대응하기 어렵다.
생성자나 정적 팩터리가 처리해야 할 매개변수가 많다면 빌더 패턴을 선택하는 게 더 낫다.
매개변수 중 다수가 필수가 아니거나 같은 타입이면 특히 더 그렇다.
빌더는 점층적 생성자보다 클라이언트 코드를 읽고 쓰기가 훨씬 간결하고, 자바빈즈보다 훨씬 안전하다.

점층적 생성자 패턴(telescoping constructor pattern)

  • 매개변수가 많아지면 클라이언트 코드를 장성하거나 읽기 어렵다.

    public 생성자(변수1);
    public 생성자(변수1, 변수2);
    public 생성자(변수1, 변수2, 변수3..);

자바빈즈 패턴(JavaBeans pattern)

  • setter를 이용
  • 객체 하나를 생성하기 위해선 여러개의 매서드 호출이 필요
  • 객체가 완전히 생성되기 전까지 일관성이 무너진 상태에 놓임

    Coffee coffee = new Americano();
    coffee.setPrice(3000);
    coffee.setCapacity(500);
    ...

빌더 패턴(Builder Pattern)

  • 필수 매개변수만으로 생성자 또는 정적 팩터리를 호출하여 빌더 객체를 얻음
public class NutritionFacts {
  private final int servingSize;
  private final int servings;
  private final int calories;
  private final int fat;

  // Builder
  public static class Builder {
    //필수 매개변수
    private final int servingSize;
    private final int servings;
    // 선택적 배개변수 - 기본값으로 초기화
    private int calories = 0;
    private int fat = 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 NutritionFacts build() { return new Nutrition(this); }
  }
  
  private NutritionFacts(Builder builder) {
    this.servingSize = builder.servingSize;
    this.servings = builder.servings;
    this.calories = builder.calories;
    this.fat = builder.fat;
  }
}

//사용
NutritionFacts cocaCola = NutritionFacts.Builder(240, 8).calories(100).build();

작업 기록 블로그