티스토리 뷰
![]() |
|
영양 성분표를 나타내는 클래스가 있다고 가정해보자
클래스의 필드
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();
'JAVA > Effective Java' 카테고리의 다른 글
규칙5 불필요한 객체는 만들지 말라 (0) | 2018.12.19 |
---|---|
규칙6 유효기간이 지난 객체 참조는 폐기하라 (0) | 2018.12.19 |
규칙4 객체 생성을 막을 때는 private 생성자를 사용하라 (0) | 2018.12.19 |
규칙3 private 생성자나 enum 자료형은 싱글턴 패턴을 따르도록 설계하자 (0) | 2018.12.19 |
규칙1 생성자 대신 정적 팩터리 메서드를 사용할 수 없는지 생각해 보라 (0) | 2018.12.19 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Flux
- mariada-connector
- MariaDB
- msyql-connector-java
- RoutePredication
- Lazy
- spring cloud gateway
- aurora
- dynamodb
- notifyAll()
- circurit breaker
- DyanomoDB
- notify()
- router
- mariadb-connector-j
- custom config data convertion
- referencedColumnName
- AbstractMethodError
- HashMap
- getBoolean
- rate limit
- reactor
- GlobalFilter
- N+1
- RouteDefinition
- Seperate Chaining
- wait()
- ConcurrentHashMap
- ResultSet
- reative
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함