여러 필드의 값을 받는 클래스의 경우 텔리스코핑 생성자 패턴을 사용하면 매번 인스턴스를 생성할 때 원하지 않는 매개변수에도 초기값을 주어야 한다.
매개변수가 많은 생성자의 경우 두번째 대안으로 자바빈즈 패턴(getter, setter를 사용하는 것)이 있는데 이것은 여러 번의 메소드 호출로 나누어져 인스턴스로 생성되므로, 생성 과정을 거치는 동안 자바빈 객체가 일관된 상태를 유지하지 못할 수 있다.
 또한 자바빈즈 패턴은 불변 클래스를 만들 수 있는 가능성을 배제함으로 thread에서 안정성을 유지하려면 개발을 할 때 추가적인 노력이 필요하다는 단점이 있다.

이래서 나온게 빌더 패턴이다.

예제는 다음과 같다

 
public class NutFacts {
 
 private final int servingSize;
 private final int calories;
 private final int fat;
 private final int sodium;
 
 public static class Builder {
  
  private final int servingSize; //필수 값
  
  private int calories; //선택값
  private int fat;  //선택값
  private int sodium; //선택값
  
  public Builder(int servingSize){
   this.servingSize = servingSize;
  }
  
  public Builder calories(int val){
   calories = val;
   return this;
  }
  
  public Builder fat(int val){
   fat = val;
   return this;
  }
  
  public Builder sodium(int val){
   sodium = val;
   return this;
  }
  
  public NutFacts build(){
   return new NutFacts(this);
  }
 }
 
 private NutFacts(Builder builder){
  servingSize = builder.servingSize;
  calories = builder.calories;
  fat = builder.fat;
  sodium = builder.sodium;
 }

}

 public class item2 {

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub

  NutFacts drink = new NutFacts.Builder(3).calories(23).build();
 }

}


그냥 자바 빈즈 패턴의 경우 getter와 setter를 만들어서 썼기 때문에 코드가 길어진다. 하지만 아래 class item2 클래스를 보면 자신이 집어넣을 필수 파라미터(Builder)를 설정하고 뒤에 옵셔널한 파라미터(calories)를 설정하도록 한다.

생성자가 static factory method에서 많은 매개 변수를 갖게 될 클래스를 설계할 때는 빌더 패턴이 좋은 선택이다. 특히 선택 매개변수가 대부분인 경우 그렇다. 그리고 그 간 사용하던 텔리스코핑 생성자 패턴보다 빌더를 사용하면 코드의 가독성이 좋고 작성도 쉬워진다. 또한 빌더는 자바빈즈 패턴보다 훨씬 안전하다.

위의 예제보다 더 좋은 예가 있는 곳을 찾았다.
아래 링크를 따라가면 마린의 속성 정보를 가지고 빌더패턴을 적용한 소스가 있다.
http://dbjavayo.tistory.com/entry/h2-생성자의-매ㅑ개변수가-많을-때는-빌더builder를-고려하자


Posted by 서오석
,