선택적 매개변수가 많을 때 적절하게 대응하기 어렵다
</br>
점층적 생성자 패턴
: 필수 매개변수만 받는 생성자 ..>..>필수 매개변수 + 선택 매개변수 전체를 받는 생성자
public class NutritionFacts {
private final int servingSize; // (ml, 1회 제공량) 필수
private final int servings; // (회, 총 n회 제공량) 필수
private final int calories; // (1회 제공량당) 선택
private final int fat; // (g/1회 제공량) 선택
private final int sodium; // (mg/1회 제공량) 선택
private final int carbohydrate; // (g/1회 제공량) 선택
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 NutritionFactsdnt 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;
}
}
단점
1. 설정을 원하지 않는 매개변수까지 포함해야하고 어쩔 수 없이 그런 매개변수에도 값을 지정해줘야 한다.
2. 매개변수가 많아지면 클라이언트 코드를 작성하거나 읽기 어렵고 에러 발생 위험이 높다.
💡 확장이 어렵다
Java Beans Pattern
: 매개변수가 없는 생성자로 객체 생성 후 setter를 통해 매개변수 값 설정
public class NutritionFacts {
// 매개변수들은 (기본값이 있다면) 기본값으로 초기화된다.
private int servingSize = -1; // 필수; 기본값 없음
private int servings = -1; // 필수; 기본값 없음
private int calories = 0;
private int fat = 0;
private int sodium = 0;
private int carbohydrate = 0;
public NutritionFactsO { }
// 세터 메서드들
public void setServingSize(int val) { servingSize = val; }
public void setServings(int val) { servings = val; }
public void setCaloriesdnt(int val) { calories = val; }
public void setFatdnt(int val) { fat = val; }
public void setSodium(int val) { sodium = val; }
public void setCarbohydrate(int val) { carbohydrate = val; }
}
💡 일관성이 깨지고 불변으로 만들 수 없다.
: 필수 매개변수로 생성자를 호출해 빌더 객체를 얻음
클래스 안에 정적 멤버 클래스로 생성
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 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;
}
☀️ 핵심정리
생성자나 정적 팩터리가 처리해야하 할 매개변수가 많다면 빌더 패턴을 선택하는게 더 낫다. 매개변수 중 다수가 필수가 아니거나 같은 타입이면 특히 더 그렇다. 빌더는 점층적 생성자보다 클라이언트 코드를 읽고 쓰기가 훨씬 간결하고 자바빈즈보다 훨씬 안전하다.
덕분에 이펙티브 자바를 공부하네요 ... 넘조아요