상황
- 매개변수 중 다수가 필수가 아니거나 같은 타입인 상황
대응 방안
점층적 생성자 패턴
- 필수 매개변수와 선택 매개변수 1개를 받는 생성자, 선택 매개변수를 2개까지 받는 생성자... 등 선택 매개변수를 전부 다 받는 생성자까지 늘려가는 방식임. ⇒ 매개변수가 너무 많아지면 클라이언트 코드 쪽에서 작성하거나 읽기가 어려움
NutritionFacts cocaCola = new NutritionFacts(240, 8, 100, 0, 35, 27);
// 각각의 파라미터가 무엇을 의미하는지 알 수 없음! 위치 잘못 넣을 수 도 있고
자바 빈즈
- 매개 변수가 없는 생성자로 객체를 만든 후, 세터 메서드들을 호출해 원하는 매개변수의 값을 설정하는 방식임
- 읽기 쉬운 코드가 되기는 함.
- 그러나, 객체 하나를 만들기 위해 여러 메서드를 여러 줄로 호출해야 함
- 객체가 완전히 생성되기 전까지는 일관성이 무너져 있음 ← 점층적 생성자 패턴에서는 매개변수들이 유효한지를 생성자에서만 확인하여 일관성 유지가 가능했는데 이 장치가 사라진 것
- 그래서, 클래스를 불변으로 만들 수 없음 ⇒ Thread-safety를 얻기 위해서는 프로그래머가 추가 작업을 해주어야함
빌더 패턴
- 클라이언트가 필요한 객체를 직접 만드는 대신, 필수 매개변수 만으로 생성자(혹은 정적 팩터리)를 호출해 빌더 객체를 얻음
- 빌더 객체의 세터 메서드들로 원하는 선택 매개변수 설정
- build() 를 호출하여 필요한 객체 생성
- 빌더 객체의 세터 메서드들은 전부 빌더 자신을 반환하기 때문에 method chaining이 가능함
- 매개변수의 유효성 검사는 각각의 세터 메서드들, 그리고 build( ) 에서 실행 가능함
- 사소한 이점 : 빌더를 이용하면 가변인수 매개변수(
String ...
)를 여러 개 사용할 수 있음. 이것을 적절히 여러 메서드에 나눠서 인자로 받을 수 있는 것. - 아래와 같이 메서드를 여러 번 체이닝 해서 호출하게 되는데 여러 메서드에서 전달된 파라미터를 하나의 필드로 모을 수도 있음.
Calzone calzone = new Calzone.Builder().addTopping(HAM).sacueInside().build();
핵심
- 빌더는 점층적 생성자보다 클라이언트 코드를 읽고 쓰기가 훨씬 간결하고, 자바빈즈 보다 훨씬 안전함.