02. 생성자 파라미터가 많을 경우 빌더를 고려해보자.
Joshua Bloch 저 「Effective Java 3rd Edition, 2018」를 읽고 정리하였습니다.
1. 점층적 생성자 패턴
점층적 생성자 패턴(telescoping constructor pattern) 영양분 정보를 가진 객체를 만들어보자.
public 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 NutritionFacts(int servingSize, int servings) {
this(servingSize, servings, 0);
}
public NutritionFacts(int servingSize, int servings,
int calories) {
this(servingSize, servings, calories, 0);
}
public NutritionFacts(int servingSize, int servings,
int calories, int fat) {
this(servingSize, servings, calories, fat, 0);
}
public NutritionFacts(int servingSize, int servings,
int calories, int fat, int sodium) {
this(servingSize, servings, calories, fat, sodium, 0);
}
public NutritionFacts(int servingSize, int servings,
int calories, int fat, int sodium, int carbohydrate) {
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = fat;
this.sodium = sodium;
this.carbohydrate = carbohydrate;
}
}매개변수 6개 조합을 일일이 만들어 줘야되 코드가 너무 길어진다. 그리고 지금은 매개변수가 6개 밖에 없지만 많아질 수록 더욱 복잡해질 것이다.
2. 자바빈즈 패턴
위와 같은 상황을 대응하기 위해서 자바 빈즈패턴 사용을 고려할 수 있다.
인스턴스를 만들기 더 쉬워졌고, 필수 매개변수와 선택 매개변수를 구분해서 받아들일 수 있다. 하지만 자바빈즈의 경우에도 심각한 단점이 하나 있다. 바로 객체의 불변성을 보장하지 못해 객체의 일관성이 훼손될 수도 있다.
3. 빌더 패턴
점층적 생성자 패턴의 안전성 장점과, 자바 빈즈 패턴의 가독성 장점을 모두 가져온 빌더패턴을 알아보자.
Setter를 보면 빌더 자신을 반환하기 때문에 연쇄적으로 호출할 수 있다(메서드 체이닝).
롬복의 @Builder 어노테이션을 사용하면 다 작성해 줄 필요가 없다.
정리
빌더 패턴과 자바 빈즈 패턴의 가장 큰 차이점은 불변성에 있다.
자바 빈즈 패턴은 객체를 생성한 후, 값을 setter 메서드를 통해 넣는다. 그렇기에 객체 사용 도중 실수로, 혹은 악의적인 목적으로 setter 메서드를 통해 유효하지 않은 값이나 null값, 혹은 정확하지 않은 값이 들어갈 수 있다.
반면, 빌더 패턴은 객체 생성 전, 값을 setter 메서드를 통해 넣는다. 그리고 다 넣었다면 마지막에 build 메서드를 호출하여 객체를 생성한다. 그렇기 때문에 객체 사용 중에 값이 변경될 우려가 없으며, 불변성과 안정성이 올라간다. 당연하지만, 빌더 패턴 사용시에는 public setter 메서드를 선언해서는 안된다.
Last updated