티스토리 뷰

이펙티브 자바 Effective Java 2/E
국내도서
저자 : 조슈아 블로크(Joshua Bloch) / 이병준역
출판 : 인사이트 2014.09.01
상세보기

영양 성분표를 나타내는 클래스가 있다고 가정해보자
클래스의 필드
 1. 총 제공량
 2. 1회 제공량
 3. 1회 제공량당 칼로리
 4. 총 지방 함량 
 . . .
 위 클래스를 코드로 나타내면 다음과 같다.

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 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 NutritionFacts (int 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; } } NutritionFacts cocaCola = new NutritionFacts(100, 20, 1, 0);

저 생성자를 사용할 생각만 하면 지옥과 같다.


set 함수를 사용하면 코드양과 가독성이 좋아진다.

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 void setServingSize(int servingSize) { this.servingSize = servingSize; } public void setServing(int serving) { this.serving = serving; } public void setCalories(int calories) { this.calories = calories; } public void setFat(int fat) { this.fat = fat; } } NutritionFacts cocaCola = new NutritionFacts(); cocaCola.setServingSize(100); cocaCola.setServing(8); cocaCola.setCalores(100);

하지만 set 패턴은 1회의 함수 호출로 객체 생성을 끝낼 수 없으므로 객체 일관성이 일시적으로 깨질 수 있다. 객체일관성이 깨진 객체는 디버깅에 어려움을 겪게될 수 있다.
또한, 변경 불가능(immutable) 클래스를 만들 수 없으므로 스레드 안정성을 제공하기 위해 할 일이 많아진다.

이런 문제점들을 해결하기 위해 Builder 패턴을 사용한다

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 sodium = 0; private 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 carbohydrate (int val) { carbohydrate = val; return this; } public Builder sodium (int val) { sodium = val; return this; } public NutritionFacts build() { return new NutritionFacts(this); } } private NutritionFacts (Builder builder) { servingSize = builder.servingSize; servings = builder.servings; calories = builder.calories; sodium = builder.sodium; fat = builder.fat; carbohydrate = builder.carbohydrate; } } NutritionFacts cocaCola = new NutritionFacts.Builder(10, 8).calories(100).sodium(35).carbohydrate(27).build();


공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함