서론
- 정적 팩터리와 생성자는 선택적 매개변수가 많을 때 적절히 대응하기 어렵다는 제약을 가짐
- 이를 해결하기 위한 개발자의 접근
1. 점층적 생성자 패턴(Telescoping Constructor Pattern)
- 말 그대로 점층적인 생성자 패턴
- 필수 매개변수부터 모든 경우의 수의 선택 매개변수를 받는 생성자까지 늘려가는 방식
- 하늘쓰 식으로 말을 표현하자면 "오버라이딩의 끝판왕"으로 생성자를 늘려감
- 인스턴스 생성시 원하는 매개변수를 포함한 생성자 중 가장 짧은 것을 고르면 됨
- 확장이 어렵다는 한계를 가짐
- 매개변수의 수가 많아질 경우 클라이언트 코드를 작성하거나 읽기가 어려움
- Intellij의 경우 매개변수가 무엇인지 표기되어 비교적 Human Error 발생 가능성이 낮지만,
매개변수 값을 잘못 입력하는 일이 발생할 수 있음
2. 자바빈즈 패턴(JavaBeans Pattern)
- 세터(Setter) 메서드들을 호출해 원하는 매개변수 값을 설정하는 방식'
- '점층적 생성자'의 한계인 값에 대한 구분 문제를 해결할 수 있음
- 각 setOOO, isOOO 메서드로 값을 할당하기에 매개인자로 값을 잘못 넘겨주는 에러를 해소할 수 있음
- 하지만 객체 하나 만들기 위해 메서드 여러 개를 호출하고, 완전히 완성되기 전까지 일관성(consistency)가 무너진 상태에 놓인다는 심각한 한계가 존재함
일관성이 깨진 객체
- 버그를 심은 코드와 해당 버그 때문에 런타임에 문제를 겪는 코드가 물리적으로 멀리 떨어져있어 디버깅이 쉽지 않음
- 쉽게 말하자면 버그가 발생한 코드랑 런타임에서 발생하는 문제 코드를 찾아야 하는데 이들을 하나 하나 일일히 설정하기에 디버깅이 쉽지 않다는 뜻임
이로 일관성이 무너져 클래스를 불변으로 만들 수 없어, 스레드의 안전성을 위해 추가 작업이 필요하게 됨
=> 해당 단점 보완을 위해 얼리기(freezing) 전까지 사용할 수 없도록 하기도 하지만, 이를 사용하더라도 개발자가 freeze 메서드를 확실히 호출해줬는지 컴파일러가 보증할 방법이 없어 런타임 오류에 취약함
[Java] Immutable Class (불변 클래스) (tistory.com)
3. 빌더 패턴(Builder Pattern)
- 필요한 객체를 직접 만드는 대신 필수 매개변수만 생성자를 호출해 빌더 객체를 얻으며,
빌더 객체가 제공하는 일종의 Setter 메서드들로 원하는 선택 배개변수들을 설정함 - 이는 매개변수가 없는 build 메서드를 호출해 필요한 객체를 얻을 수 있음
- 계층적으로 설계된 클래스와 함께 쓰기에 좋음
- 추상 클래스 = 추상 빌더
- 구체 클래스 = 구체 빌더
빌더 패턴 활용
- Builder(빌더)는 생성할 클래스 안에 정적 멤버 클래스로 만드는 것이 보통임
- 이외에 Lombok의 어노테이션을 사용해 Builder 패턴을 적용하기도 함
- 플루언트 API(Fluent API) 혹은 메서드 연쇄(Method chaining) 가능
Builder의 Setter Method들은 빌더 자신을 반환하기에 연쇄적 호출이 가능함
Lombok(롬복)을 적용한 Builder Pattern