해당 포스트는 "자바 객체지향 디자인 패턴", "JAVA 언어로 배우는 디자인 패턴 입문" 책의 내용을 요약한 것이다.



※ 빌더 패턴

: 빌더 패턴은 클래스에서 받아야할 인자들이 많거나(최소 4개 이상), 선택적 인자들이 많거나, 추가될 인자들이 많을 경우 사용한다.

 

ex)

 

public class Person{
   private String gender;               // 필수로 받아야 하는 인자
   private String age;                   // 선택적으로 받는 인자
   private String work;                 // 선택적으로 받는 인자
   public Person(String gender){
         this.gender = gender;
   }
   public Person(String gender, String age){
         this.gender = gender;
         this.age = age;
   }
   public Person(String gender, String age, String work){
         this.gender = gender;
         this.age = age;
         this.work = work;
   }
}

위와 같은 방식으로 클래스를 구현할 경우 인자들이 많아질수록 생성자의 숫자가 많아지고 메인 프로그램에서 생성자를 통해 객체를 생성할 때 매개변수의 정보를 알 수 없어 매개변수로 들어갈 인자들이 서로 바뀌거나 잘못 들어갈 수도 있다.

 

 

public class Person{
   private String gender;               // 필수로 받아야 하는 인자
   private String age;                   // 선택적으로 받는 인자
   private String work;                 // 선택적으로 받는 인자
   public void setGender(String gender){
         this.gender = gender;
   }
   public void setAge(String age){
        this.age = age;
   }
   public void setWork(String work){
        this.work = work;
   }
}

위와 같은 방식은 생성자의 단점으로 뽑혔던 가독성이 해결이 되지만 실제 메인 프로그램에서 인스턴스를 생성할 때 코드량이 늘어나고 언제든지 set 메서드로 인스턴스 필드의 변경이 가능하기에 객체의 일관성이 깨진다. 즉, 한 번 객체를 생성할 때 그 객체가 변할 여지가 존재한다.

 

public class Person{
   private String gender;               // 필수로 받아야 하는 인자
   private String age;                   // 선택적으로 받는 인자
   private String work;                 // 선택적으로 받는 인자
   
   public static class PersonBuilder{
       private String gender;
       private String age;
       private String work;
 
       public PersonBuilder(String gender){
           this.gender = gender;
       }
       public PersonBuilder setAge(String age){
           this.age = age;
           return this;
       }
       public PersonBuilder setWork(String work){
           this.work = work;
           return this;
       }
       public Person build(){
           return new Person(this);
        }
   }
    private Person(PersonBuilder builder){
         this.gender = builder.gender;
         this.age = builder.age;
         this.work = builder.work;
    }
} 

public class Main {
     public static void main(String[] args){
         Person person = new Person.PersonBuilder("남자").setAge("11")
                                        .setWork("회사").build();
     }
}

위 빌더 패턴 방식은 두 번째 예처럼 자바빈즈 패턴처럼 받되, 데이터의 일관성을 위해 정보들을 다 받은 후에 객체를 생성한다. 또한 가독성도 좋다. 하지만 많은 코드량이 필요할 뿐만 아니라 Builder 객체를 하나 더 만드는 것으로 성능이 낮아질 수는 있다. 그래도 받아야 할 인자들이 많거나 선택적 인자, 추가될 인자들이 많다면 Builder 패턴을 쓰는 것이 좋다.



※ Effective Java 책에 나오는 빌더 패턴 적용

: 생성자를 이용할 때 인자 수가 늘어나면 코드를 작성하기가 어려워지고 무엇보다 읽기 어려운 코드가 된다. 자바 빈을 활용해 객체를 생성하면 1회의 함수 호출로 객체 생성을 끝낼 수 없다. 따라서 객체의 일관성이 깨지고 디버깅하기도 어렵다. 또한 변경 불가능 클래스를 만들 수 없고 스레드의 안정성을 보장하기 어렵다.  이런 단점들을 보완한 빌더 패턴은 생성자를 이용할 때의 안정성과 자바 빈을 이용할 때의 가독성을 결합한 것이다. 

빌더 패턴에도 단점이 있다. 객체를 생성하려면 빌더 객체를 생성해야 한다. 실무에서 빌더 객체를 만드는 오버헤드가 문제가 될 소지는 없을 수 있으나 성능이 중요한 상황에선 그렇지 않을 수도 있다. 따라서 빌더 패턴은 인자가 많은 생성자나 대부분의 이나가 선택적 인자인 상황에 유용하다.

'자바 > 디자인패턴' 카테고리의 다른 글

디자인 패턴  (0) 2017.06.29
책임 연쇄/사슬 패턴  (0) 2017.06.08
플라이웨이트 패턴  (0) 2017.06.08
퍼사드 패턴  (0) 2017.06.08
프로토타입 패턴  (0) 2017.06.08

+ Recent posts