아이템 2 : 생성자에 매개변수가 많다면 빌더를 고려하라
정적 팩터리와 생성자에는 똑같은 제약이 하나 있다. 선택적 매개변수가 많을 때 적절히 대응하기 어렵다는 점이다.
이런 클래스용 생성자 혹은 정적 팩터리는 어떤 모습일까? 프로그래머들은 이럴 때 점층적 생성자 패턴을 즐겨 사용했다. 필수 매개변수만 받는 생성자, 필수 매개변수와 선택 매개변수 1개를 받는 생성자, ... 형태로 선택 매개변수를 전부 다 받는 생성자까지 늘려가는 방식이다.
매개변수가 많더라도 점층적 생성자 패턴도 쓸 수는 있지만, 매개변수 개수가 많아지면 클라이언트 코드를 작성하거나 읽기가 어려워진다.
선택 매개변수가 많을 때 활용할 수 있는 다른 대안이 있다. 바로 자바빈즈 패턴이다.
매개변수가 없는 생성자로 객체를 만든 후, 세터 메서드들을 호출해 원하는 매개변수의 값을 설정하는 방식이다.
하자민 자바빈즈는 심각한 단점을 지니고 있다. 자바빈즈 패턴에서는 객체 하나를 만들려면 메서드를 여러 개 호출해야 하고, 객체가 완전히 생성되기 전까지는 일관성이 무너진 상태에 놓이게 된다.
이처럼 일관성이 무너지는 문제 때문에 자바빈즈 패턴에서는 클래스를 불변으로 만들 수 없으며 스레드 안전성을 얻으려면 프로그래머가 추가 작업을 해줘야만 한다.
다행히 다른 대안이 존재한다. 점층적 생성자 패턴의 안전성과 자바빈즈 패턴의 가독성을 겸비한 빌더 패턴이다.
클라이언트는 필요한 객체를 직접 만드는 대신, 필수 매개변수만으로 생성자(혹은 정적 팩터리)를 호출해 빌더 객체를 얻는다. 그런 다음 빌더 객체가 제공하는 일종의 세터 메서드들로 원하는 선택 매개변수들을 설정한다. 마지막으로 매개변수가 없는 build 메서드를 호출해 우리에게 필요한(보통은 불변인) 객체를 얻는다.
빌더 패턴은 계층적으로 설계된 클래스와 함께 쓰기에 좋다.
핵심 정리
생성자나 정적 팩터리가 처리해야 할 매개변수가 많다면 빌더 패턴을 선택하는 게 더 낫다. 매개변수 중 다수가 필수가 아니거나 같은 타입이면 특히 더 그렇다. 빌더는 점층적 생성자보다 클라이언트 코드를 읽고 쓰기가 훨씬 간결하고, 자바빈즈보다 훨씬 안전하다.
'언어 > JAVA' 카테고리의 다른 글
[Effective Java] 불필요한 객체 생성을 피하라 (0) | 2020.03.11 |
---|---|
[Effective Java] 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (0) | 2020.03.11 |
[Effective Java] 인스턴스화를 막으려거든 private 생성자를 사용하라 (0) | 2020.03.10 |
[Effective Java] private 생성자나 열거 타입으로 싱글턴임을 보증하라 (0) | 2020.03.10 |
[Effective Java] 생성자 대신 정적 팩터리 메서드를 고려하라 (0) | 2020.03.09 |