본문 바로가기
Java/Effective Java 3E

[이펙티브자바 3판] ITEM2. 생성자에 매개변수가 많다면 빌더를 고려하라

by 잭피 2020. 9. 3.

이번장의 핵심은...

생성자나 정적 팩터리가 처리해야 할 매개변수가 많다면 빌더 패턴을 선택하는게 더 낫다

→ 매개변수 중 다수가 필수가 아니거나 같은 타입이면 특히 더 그렇다.

빌더는 점층적 생성자보다 클라이언트 코드를 읽고 쓰기가 훨씬 간결하고, 자바빈즈보다 훨씬 안전함


점층적 생성자 패턴

A a = new A(240,2,2,3,4,...)

→ 매개변수 개수가 많아지면 클라이언트 코드를 작성하거나 읽기 어려움

자바빈즈 패턴

→ 매개변수가 없는 생성자로 객체를 만든 후, setter 메서드들을 호출해 원하는 매개변수의 값을 설정하는 방식

A a = new A(); a.setName(~); a.setAge(~);

→ 자바빈즈 패턴에서는 객체 하나를 만들려면 메서드를 여러 개 호출해야 하고, 객체가 완전히 생성되기 전까지는 일관성이 무너진 상태에 놓이게 됨

빌더 패턴

→ 점층적 생성자 패턴의 안정성과 자바빈즈 패턴의 가독성을 겸비

빌더는 보통 생성할 클래스 안에 정적 멤버 클래스로 만들어둠

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 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;
		    }
		
    public static void main(String[] args) {
        NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8)
                .calories(100).sodium(35).carbohydrate(27).build();
    }
  }

-> 빌더 패턴은 계층적으로 설계된 클래스와 함께 쓰기에 좋다

 

댓글