2. 생성자에 매개변수가 많다면 빌더를 고려하라
2. 생성자에 매개변수가 많다면 빌더를 고려하라
📂 item02_builder_pattern.md
item02_builder_pattern.md
📖 아이템 2: 생성자에 매개변수가 많다면 빌더를 고려하라
🧩 빌더(Builder) 패턴이란?
빌더 패턴(Builder Pattern)은 객체를 만들 때 매개변수가 많을 경우 유용하게 쓰이는 디자인 패턴입니다.
생성자에 너무 많은 매개변수가 들어가면 코드가 복잡하고 가독성이 떨어지는데, 빌더 패턴은 이러한 문제를 해결해 줍니다.
📌 생성자에 매개변수가 많을 때의 문제점
객체를 생성할 때 아래의 문제들이 발생할 수 있습니다.
점층적 생성자 패턴 (Telescoping Constructor Pattern)
생성자를 여러 개 만들고, 매개변수를 조금씩 다르게 해서 여러 개를 정의하는 방식.
단점: 코드가 길고, 읽기 어렵고, 순서를 잘못 넣기 쉬움.
예시 코드
NutritionFacts coke = new NutritionFacts(240, 8, 100, 0, 35, 27);
// 각 숫자의 의미를 알기 어렵다.
자바빈즈(JavaBeans) 패턴
객체를 먼저 만들고, 세터(setter)를 사용하여 나중에 값을 설정하는 방식.
단점: 객체 생성과 값 설정이 분리되어, 값이 완전하지 않은 상태로 객체가 사용될 수 있음.
예시 코드
NutritionFacts coke = new NutritionFacts();
coke.setServingSize(240);
coke.setServings(8);
coke.setCalories(100);
// 값 설정이 누락될 가능성이 높음!
✅ 빌더 패턴의 장점 및 핵심 개념
1️⃣ 명확한 코드 작성 가능
빌더 패턴은 매개변수의 이름을 명시적으로 보여줌으로써 코드가 읽기 쉬워집니다.
빌더를 활용한 객체 생성 예시
NutritionFacts coke = new NutritionFacts.Builder(240, 8)
.calories(100)
.sodium(35)
.carbohydrate(27)
.build();
메서드가 연쇄적으로 연결되는 방식(method chaining)이라 코드의 의미가 명확해짐.
2️⃣ 빌더 패턴의 기본 구조
빌더 패턴은 클래스 내부에 **정적 내부 클래스(static inner class)**로 정의하여 사용합니다.
public class NutritionFacts {
// 필수 멤버 변수
private final int servingSize;
private final int servings;
// 선택 멤버 변수 (기본값 설정 가능)
private final int calories;
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 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 sodium(int val) {
sodium = val;
return this;
}
public Builder carbohydrate(int val) {
carbohydrate = val;
return this;
}
public NutritionFacts build() {
return new NutritionFacts(this);
}
}
// Builder를 받아 객체를 생성하는 private 생성자
private NutritionFacts(Builder builder) {
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
sodium = builder.sodium;
carbohydrate = builder.carbohydrate;
}
}
🛠️ 빌더 패턴을 언제 사용하면 좋을까?
클래스의 생성자나 정적 팩터리가 처리해야 할 매개변수가 많을 때
매개변수 중 일부만 필수이고 나머지는 선택적일 때
특히 매개변수가 많거나 같은 타입의 매개변수가 여러 개 있을 때
📌 빌더 패턴의 장점
✅ 가독성: 매개변수가 많아도 각 값이 어떤 의미인지 명확하게 보입니다.
✅ 유연성: 선택적인 매개변수 처리가 매우 편리합니다.
✅ 안정성: 객체가 생성된 후에는 변경되지 않게 만들어(불변성) 안정성을 높입니다.
✅ 계층적 설계에 유리: 상속이 많아도 깔끔한 코드 유지가 가능합니다.
⚠️ 빌더 패턴의 단점
구현의 복잡성: 초기 구현 시 클래스와 빌더 클래스를 따로 만들어야 합니다.
코드 길이 증가: 클래스가 작고 단순할 경우, 오히려 빌더 패턴이 더 번거로울 수 있습니다.
📚 핵심 용어
빌더 패턴 (Builder Pattern): 객체를 만들 때 빌더 객체를 따로 두고 생성 과정을 깔끔하게 정리하는 방법.
메서드 체이닝 (method chaining): 메서드가 계속 이어져서 호출되는 형태.
플루언트 API (fluent API): 코드가 자연스럽게 읽히도록 메서드를 연쇄적으로 연결하는 스타일.
불변 객체 (immutable object): 생성 후 상태가 변하지 않는 객체로, 안정성이 높음.
✨ Nutshell (한눈에 요약)
빌더 패턴은 매개변수가 많은 객체를 명확하게, 안전하게, 편리하게 생성하는 디자인 방법입니다.
빌더를 사용하면:
매개변수가 많은 객체도 쉽게 생성 가능
가독성과 유지보수성을 높이고 휴먼 에러를 방지
코드가 명확해지고 직관적이 됩니다.
🔑 한 줄 결론: 매개변수가 많고 복잡한 클래스는 빌더 패턴을 쓰면 코드가 명확해지고 실수가 줄어듭니다.
Last updated