[BooksReview] effectiveJava - 생성자의 builder패턴 적용(builder pattern)
BooksReview/effective Java 2017. 10. 8. 19:11생성자의 builder패턴 적용(builder pattern)
1. 생성자의 문제
1) 선택적 인자가 많은 상황에 잘 적응하지 못한다
2. 점층적 생성자 패턴(telescroping constructor pattern)
- 필요한 생성자를 하나씩 추가하는 방식
public
class
NutritionFacts {
private
final
int
servingSize;
private
final
int
servings;
private
final
int
calories;
private
final
int
fat;
public
NutritionFacts(
int
servingSize,
int
servings) {
this
(servingSize, servings,
0
,
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 = servingSize;
this
.servings = servings;
this
.calories = calories;
this
.fat = fat;
}
}
1) 문제점
- 설정할 필요없는 값(위의 0 같은)을 설정해야한다.
- 점층적 생성자 패턴은 잘 동작하지만 클라이언트 코드 작성이 어렵고 가독성이 떨어진다.
3. 자바빈 패턴(JavaBeans pattern)
- 인자 없는 생성자를 호출하여 객체를 만든다음 설정 메소드로 필드값을 추가하는 방식
public
class
NutritionFacts {
private
int
servingSize = -
1
;
private
int
servings = -
1
;
private
int
calories =
0
;
private
int
fat =
0
;
public
int
getServingSize() {
return
servingSize;
}
public
void
setServingSize(
int
servingSize) {
this
.servingSize = servingSize;
}
public
int
getServings() {
return
servings;
}
public
void
setServings(
int
servings) {
this
.servings = servings;
}
public
int
getCalories() {
return
calories;
}
public
void
setCalories(
int
calories) {
this
.calories = calories;
}
public
int
getFat() {
return
fat;
}
public
void
setFat(
int
fat) {
this
.fat = fat;
}
}
- 사용
NutritionFacts coke =
new
NutritionFacts();
cock.setServingSize(
240
);
cock.setServings(
100
);
....
1) 문제점
- 1회의 함수 호출로 객체 생성을 끝낼수 없다.(객체의 일관성이 일시적으로 깨진다)
- 변경 불가능 클래스(immutable)를 만들 수 없다.
4. 빌더패턴(builder pattern)
- 점층적 생성자 패턴 + 자바빈 패턴
- 필요한 객체를 직접 생성하는 대신, 클라이언트는 먼저 필수 인자들을 생성자에 전부 전달하여 빌더 객체를 만든다.
- 빌더 객체에 정의된 설정 메소드를 호출하어 선택적 인자를 추가한다.
public
class
NutritionFacts {
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) {
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
NutritionFacts build() {
return
new
NutritionFacts(
this
);
}
}
private
NutritionFacts(Builder builder) {
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
}
}
- 사용
NutritionFacts coke =
new
NutritionFacts.Builder(
240
,
8
).calories(
100
).fat(
0
).build();
1) 장점
- 불변식(invariant) 적용이 가능하다. build() 해당 불변식이 위반되었는지 검사가 가능하다.
- 여러개의 varargs 인자를 받을 수 있다.
- 유연하다. 하나의 빌더 객체로 여러 객체를 만들 수 있다.
2) 단점
- 객체를 생성하려면 먼저 빌더 객체를 생성해야한다.
'BooksReview > effective Java' 카테고리의 다른 글
[BooksReview]effective java - 생성자 vs 정적팩토리메소드(Constructor vs static factory method) (0) | 2017.09.10 |
---|---|
[BooksReview] effectiveJava - for문보다는 for-each문 사용 (0) | 2017.08.27 |
[BooksReview] effectiveJava - 지역변수의 유효범위 최소화 (0) | 2017.08.27 |