티스토리 뷰

공부/T.I.L(2021)

TIL - Builder패턴

크덩크덩 2021. 1. 30. 14:46
//사용방법
Book book = new Builder("MYBOOK").setContent("IT"),setAutor("JINSUB").build();​
public class Book {

  private String title;
  private String content;
  private String author;


public Book(String title) {

}

public void setTitle(String title) {
	this.title = title;
}

public void setContent(String content) {
	this.title = title;
}


//...이하 파라미터별 set함수

Vo Class 및 DTO Class를 설계할 때, 필요한 인자들을 선택적으로 받아야할 경우가 있다.(DB 필수(require) 엔티티)

이럴 때, 선택적으로 받야야할 인저를 위해 오버로딩하는 생성자 매개변수 조합이 많아진다. 

 

예를 들면 ,

에서 생성자의 조합은 3*2*1 = 6개의 조합이 있다.

이는 인자가 하나가 늘어날 수록 생성자 숫자가 크게 늘어나고, 매개변수의 순서 및 자료형을 실수할 가능성이 크게 증가한다. 

우선 코딩량이 매우 많아진다. 

 

이에 대한 대안으로 나온 것이 자바빈즈(JAVA Beans)패턴이다.

public class Book {

  private String title;
  private String content;
  private String author;


public Book(String title) {
	this.title = title;

}

public Book(String title, String content) {
	this.title = title;
    this.content = content;
    
}

//...이하 파라미터 조합마다 생성자
Book book = new Book();
book.setTitle("MYBOOK");
book.setContent("IT");

//...사용방법

 

이렇게하면 코드량은 줄고 가독성이 좋아지지만 객체의 일관성이 깨지게된다.

외부에서 set함수를 통해 객체 내부 정보에 접근할 수 있다.

따라서 언제 어디서 해당 인스턴스 값들을 Set해줘야하는지 코드상에서 명확하게 구분하기 애매해진다.

(이 때 내부를 변경하기 위해서는 명확한 행동명의 함수를 만드는 것이 추천됨  ex. public void 책이름변경( ){ ... } 

또한 1회의 호출로 객체 생성이 끝나는 것이 아니라 여러번 호출하게 된다 .

 

 

 

따라서 마지막 최종진화형인 Builder 패턴을 사용할 수 있다.

public class Book{

    private String title;
    private String content;
    private String author;

    private Book(){

    }

    //빌더패턴
    public static class Builder{

        private String title;
        private String content;
        private String author;

        //빌더의 생성자 !* title 필수 엔티티라고 가정 *!
          	public Builder(String title){
            this.title = title; //필수 엔티티

        }

        public Builder setContent(String content){
            this.cotent = content;
            return this; //여기서 메서드 체이닝 가능
        }

        public Builder setAuthor(String author){
            this.author = author;
            return this;
        }

        //최종으로 빌드를 해주는 Builder내부함수;
        public Book build(){
            Book book = new Book();

            book.title = title;
            book.content = content;
            book.author = author;

            return book;
        }
    }
    
}
//사용

Boob book = new Book.Builder("mybook").setContent("IT").setAutor("JINUSB").build();

 

2번 자바 빈즈패턴과 차이점은 set함수에서 Book Class의 내부 클래스인 Builder Class로 리턴을 해준다 .

그리고 빌더 내부함수인 build()에서 book인스턴스를 리턴해준다.


만약

 

pubilc Example(Stirng a, String b){

    this.a = a

    this.b =b

}

일 경우 new example(b,a)처럼 실수가 있어도 코드 실행 전까지 문제를 찾을 수 없다.

빌더 패턴을 이용하면 new example.builder().set_a(a).set_b(b).build(); 처럼 명확하게 인지 가능한 객체지향적인 코드를 완성할 수 있다.

즉 VO클래스 내부에서 Builer객체를 하나 더 만들어서 메서드 체이닝으로 객체를 생성한다.

이렇게 하면 외부에서 객체 내부를 수정할 방법은 객체를 통해 클래스의 정보를 분석해 내는 프로그램 기법(리플렉션) 밖에 없다.(메세지)

단점은 객체를 하나 더 만들어서 때에 따라서는 성능이 낮아진다는 것 하지만 완벽하게 객체지향적인 패턴이다.

 

 

정리하자면

빌더 패턴은 객체지향적인 측면으로 별도의 Builder 클래스를 만들어 필수 값에 대해서는 생성자를 통해, 선택적인 값들에 대해서는 메소드를 통해 step-by-step으로 값을 입력받은 후에 build() 메소드를 통해 최종적으로 하나의 인스턴스를 리턴하는 방식

 

보기에 헷갈리지만 하나씩 따라가다보면 말이된다.

롬복에서  생성자 위에 @Builder 어노테이션 하나로 완성이 가능하다. 굳..

 

 

참고자료

johngrib.github.io/wiki/builder-pattern/

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함