본문 바로가기

reviews/Effective JAVA

002. 생성자에 매개변수가 많다면 빌더를 고려하라

선택적 매개변수가 많을 때 선택할 수 있는 세가지 패턴

1. 점층적 생성자 패턴(telescoping constructor pattern)

필수 매개변수만 받는 생성자, 필수 매개변수와 선택 매개변수 1개를 받는 생성자, 선택 매개변수를 2개까지 받는 생성자, ... 형태로 늘려가며 매개변수를 전부 다 받는 생성자까지 늘려가는 방식

단점

  • 매개변수 개수가 많아지면 클라이언트 코드를 작성하거나 읽기 어렵다.
  • 사용자가 설정하길 원치 않는 매개변수가 있어도 지정하지 않을 수 없다.
  • 클라이언트가 실수로 매개변수의 순서를 바꿔도 컴파일 오류가 발생하지 않아 런타임 시 오동작 할 수 있다.

2. 자바빈즈 패턴(JavaBeans Pattern)

매개변수가 없는 생성자로 객체를 만든 후 setter 메서드들을 호출해 원하는 매개변수의 값을 설정

단점

  • 하나의 객체를 만들기 위해 여러번의 메서드를 호출해야 한다.
  • 객체가 완전히 생성되기 전까지 일관성이 깨진다.
  • 일관성이 무너지므로 불변으로 만들 수 없다.

3. 빌터 패턴(Builder Pattern)

필수 매개변수만으로 생성자(혹은 정적 팩터리)를 호출해 빌더 객체를 얻고 빌더 객체가 제공하는 일종의 세터 메서드들로 원하는 선택 매개변수들을 설정한 후 빌더 객체가 제공하는 build 매서드를 호출해 (보통은) 불변 객체를 얻는다.

빌더의 세터 메서드들은 빌더 자신을 반환하기 때문에 연쇄적으로 호출할 수 있다는 점에서 fluent API 혹은 메서드 연쇄(method chaining)이라고 한다.

(파이썬과 스칼라에 있는) 명명된 선택적 매개변수(named optional parameters)를 흉내낸 것이다.

빌더는 생성할 클래스 안에 정적 멤버 클래스로 만드는 게 일반적이다.

/** builder.* 참고 */

빌더 패턴을 선택할만한 이유

  • 계층적으로 설계된 클래스와 함께 쓰기에 좋다.
  • 매개변수 중 다수가 빌수가 아니거나 같은 타입인 경우 좋은 선택일 수 있다.
  • 점층적 생성자 패턴보다 간결하고, 자바빈즈 패턴보다 안전하다.

단점

  • 객체를 만들려면 빌더부터 만들어야 하기 때문에 성능에 민감한 상황에서는 문제가 될 수 있다.
  • 코드가 장황해서 매개변수가 많~아야 값어치를 한다.

잘못된 매개변수를 최대한 일찍 발견하려면

  • 빌더의 생성자와 메서드에서 입력 매개변수들을 검사하고, build 메서드가 호출하는 생성자에서 여러 매개변수에 걸친 불변식을 검사하고, 불변식을 보장하려면 빌더로부터 매개변수를 복사한 후 해당 객체 필드들도 검사해야 한다.
  • → 잘못된 경우 IllegalArgumentException
반응형