윤개발
[ITEM2] 생성자에 매개변수가 많다면 빌더를 고려하라. 본문
생성자에 매개변수가 많다면 빌더를 고려하라.
정적 팩터리 메서드나 생성자는 매개변수가 많을 때 적절히 대응하기 어렵다.
일반적으로 사용하는 다음의 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개이상은 되야 값어치를 한다.
정리
생성자나 정적팩터리가 처리해야할 매개변수가 많다면 빌더패턴을 선택하는게 낫다.
'책 내용 요약 > Effective Java 3판' 카테고리의 다른 글
[ITEM10] equals는 일반 규약을 지켜 재정의하라. (0) | 2020.04.14 |
---|---|
[ITEM9] try-finally보다는 try-with-resources를 사용하라. (0) | 2020.04.14 |
[ITEM8] finalizer와 cleaner 사용을 피하라 (0) | 2020.04.14 |
[ITEM7] 다쓴 객체 참조를 해제하라. (0) | 2020.04.14 |
[ITEM1] 생성자 대신 정적 팩토리 메소드를 고려하라. (0) | 2020.02.24 |
Comments