들어가기 전에)
객체를 생성할 때 멤버변수가 5개 이상일때 매게변수를 하나하나 다 넘겨주거나 set을 하는 경우가 있지 않은가?
예시를 보면서 문제점을 생각해보자.
식품포장의 영양정보를 표현하는 클래스를 생각해보자.
public class NutritionFacts {
private final int servingSize; //(ml, 1회 제공량). 필수
private final int servings; //(회, 총 n회 제공량). 필수
private final int calories; //(1회 제공량당). 선택
private final int fat; //(g/1회 제공량). 선택
private final int sodium; //(mg/1회 제공량). 선택
private final int carbohydrate; // (g/1회 제공량). 선택
public NutritionFacts(int servingSize, int servings) {
this(servingSize, servings, 0);
}
public Nutritionfacts(int servingsize, int servings, int calories){
this(servingSize, servings, calories, 0);
}
.....
}
필수 매개변수만 받는 생성자(servingSize,servings), 필수 매개변수 1개와 선택 매개변수 1개를 받는 생성자 이렇게 멤버변수가 여러개라면 생성자가 많아질 것이다.
그런데 매개변수가 많아지면 크드를 작성하거나 읽기 어렵다.
NutritionFacts cocaCola = new NutritionFacts(240,8,100,0,35,27);
클라이언트가 실수로 매개변수의 순서를 바꿔 건네줘도 컴파일러는 알아채지 못하고, 런타임에 엉뚱한 동작을 하게 된다.
그러면 set으로 객체를 생성해주는 건 어떨까?
NutritionFacts cocaCola = new NutritionFacts();
cocaCola. setServingSize (240);
cocaCola. setServings (8) ;
cocaCola. setCalories (100);
cocaCola.setSodium (35) ;
cocaCola. setCarbohydrate (27) ;
하지만 단점이 있다. 객체 하나를 만들려면 메서드를 여러개 호출해야하고, 객체가 완전히 생성되기 전까지는 일관성이 무너진 상태에 놓이게 된다. 일관성이 무너진 객체가 만들어지면 클래스를 불변으로 만들수없다.(인스턴스의 내부값을 수정할 수 없는 것이 불변)
그러므로 가독성과 안전성을 위해 빌더 패턴을 사용하자.
Lombok 라이브러리의 @Builder
@Builder
public class NutritionFacts {
private final int servingSize; //(ml, 1회 제공량). 필수
private final int servings; //(회, 총 n회 제공량). 필수
private final int calores; //(1회 제공량당). 선택
private final int fat; //(g/1회 제공량). 선택
private final int sodium; //(mg/1회 제공량). 선택
private final int carbohydrate; // (g/1회 제공량). 선택
}
@Builder 어노테이션을 추가하면 빌더패턴을 사용할 수 있다.
NutritionFacts cocaCola = NutritionFacts
.builder()
.servingSize(240)
.servings(8)
.calories(100)
.sodium(35)
.carbohydrate(27)
.build();
'IT 도서 > 이펙티브 자바' 카테고리의 다른 글
[클래스와 인터페이스] 추상 클래스보다는 인터페이스를 우선하라 (0) | 2023.08.01 |
---|---|
[클래스와 인터페이스] 상속보다는 컴포지션을 사용하라 (0) | 2023.08.01 |
생성자 대신 정적 팩토리 메소드를 고려하라 (0) | 2023.07.02 |