핵심 정리
생성자나 정적팩터리가 처리해야할 매개변수가 많다면 빌더 패턴을 선택하는게좋다.
매개변수 중 다수가 필수가 아니거나 같은 타입이면 특히 더 그렇다.
빌더는 점층적 생성자 보다 클라이언트 코드를 읽고 쓰기가 훨씬 간결하고, 자바빈즈보다 월씬 안전하다.
점층적 생성자 패턴 (Telescoping Constructor Pattern)
매개변수 개수가 많아지면 클라이언트 코드를 작성하거나 읽기 어렵다
public class NutntionFacts {
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
public NutntionFacts(int servingSize, int servings) { ... }
public NutntionFacts(int servingSize, int servings, int calories) { ... }
public NutntionFacts(int servingSize, int servings, int calories, int fat) { ... }
}
자바빈즈 패턴(JavaBeans Pattern)
매개변수가 없는 생성자로 객체를 만든 후, 세터(setter) 메서드들을 호출해 원하는 매개변수의 값을 설정하는 방식
객체 하나를 만들려면 메서드를 여러 개 호출해야 하고, 객체가 완전히 생성되기 전까지는 일관성(consistency)이 무너진 상태에 놓이게 된다
public class Test {
private int servingSize;
private int servings;
private int calories;
private int fat;
public Test() {}
public void setServingSize(int servingSize) {this.servingSize = servingSize;}
public void setServings(int servings) {this.servings = servings;}
public void setCalories(int calories) {this.calories = calories;}
public void setFat(int fat) {this.fat = fat;}
}
빌더 패턴(BuilderPattern)
Test 클래스는 불변, 쓰기 쉽고, 읽기 쉽다.
빌더 하나로 여러 객체를 순회하면서 만들 수 있고, 빌더에 넘기는 매개변수에 따라 다른 객체를 만들 수도 있다
public class Test {
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
public static class Builder{
private int servingSize;
private int servings;
private int calories;
private int fat;
public Builder(int servingSize, int servings, int calories, int fat) {
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = fat;
}
public Builder servingSize(int val){
servingSize = val;
return this;
}
public Builder servings(int val){
servings = val;
return this;
}
public Builder calories(int val){
calories = val;
return this;
}
public Builder fat(int val){
fat = val;
return this;
}
public Test build(){
return new Test(this);
}
}
private Test(Builder builder){
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
}
}
Test test = new Test.Builder().servingSize(1).servings(2).calories(3).fat(4).build();
추가 내용
lombok을 사용하는 경우 Builder 클래스 구현은 @builder 어노테이션으로 대체 가능하다.
'JAVA > 이펙티브 자바 3' 카테고리의 다른 글
2장 아이템6 - 불필요한 객체 생성을 피하라 (0) | 2021.04.02 |
---|---|
1장 - 용어 정리 (0) | 2021.03.22 |
2장 아이템1 - 생성자 대신 정적 팩터리 메서드를 고려하라 (0) | 2021.03.22 |