윤개발

[ITEM2] 생성자에 매개변수가 많다면 빌더를 고려하라. 본문

책 내용 요약/Effective Java 3판

[ITEM2] 생성자에 매개변수가 많다면 빌더를 고려하라.

DEV_SJ 2020. 2. 25. 15:15

생성자에 매개변수가 많다면 빌더를 고려하라.

정적 팩터리 메서드나 생성자는 매개변수가 많을 때 적절히 대응하기 어렵다.
일반적으로 사용하는 다음의 2가지 경우를 보자.

기존 패턴

1.점층적 생성자 패턴 - 필수 생성자, 선택 매개변수 1개를 받는 생성자, 선택 매개변수 2개를 받는 생성자, ..., n개를 받는 생성자
단점: 매개변수가 많아지면 클라이언트가 코드를 작성하기 어렵고 읽기도 어렵다.

2.자바빈즈 패턴 - 매개변수가 없는 생성자로 객체를 만든 후 세터를 이용해서 결정하는 방식
단점: 객체가 완성되기 전까지 일관성이 무너진 상태에 놓이게 된다.


빌더 패턴

클라이언트는 필수 생성자를 호출해 빌더 객체를 얻고 빌더 객체의 세터메소드를 사용하여 원하는 선택 매개변수를 설정한다.

객체 선언

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 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;
    }
}

클라이언트 코드

NutritionFacts cocaCola = new NutritionFacts.Builder(240,8)
      .calories(100).sodium(20).carbohydrate(27).build();

다음과 같이 빌더패턴을 사용한다면 클라이언트가 코드및 읽기가 쉬워진다.
빌더 패턴에 장점만 있는 것은 아니다. 객체를 만드려면 이전에 빌더 객체를 먼저 만들어야한다.
빌더 객체의 생성비용이 크지는 않지만 성능에 민감하다면 문제가 될 수 있다.
또한 코드가 장황해져서 매개변수가 4개이상은 되야 값어치를 한다.


정리

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

Comments