티스토리 뷰

Java

[Java] @Builder

Jane Kwon 2021. 2. 10. 16:09
반응형

 

Builder 패턴이란, 객체를 생성할 때 사용하는 패턴을 의미한다.

Person person = Person.build()
                      .name("Jane")
                      .age(30)
                      .build();

 

 

 

객체 생성 패턴 3가지

  1. 점층적 생성자 패턴
    public class Person {
        private final String name;       //필수 인자
        private final String nation;     //선택적 인자
        private final String hobby;      //선택적 인자
    
        /** 필수 생성자 **/
        public Person(String name) {
            this(name, "국가 비공개", "취미 비공개");
        }
    
        /** 1개의 선택적 인자를 받는 생성자 **/
        public Person(String name, String nation) {
            this(name, nation, "취미 비공개");
        }
    
        /** 모든 선택적 인자를 다 받는 생성자 **/
        public Person(String name, String nation, String hobby) {
            this.name = name;
            this.nation = nation;
            this.hobby = hobby;
        }
    }
    • 장점
      • new Person("제인", "국가 비공개", "취미 비공개") 같은 호출이 빈번하게 일어난다면,
        new Person("제인")으로 대체할 수 있다.
    • 단점
      • 생성자가 많으므로, 인자가 추가되는 일이 발생하면 코드 수정 다소 복잡해진다.
      • 인자수가 많을 때 호출 코드만 봐서는 의미를 알기 어렵다.
  2. 자바빈 패턴 (Setter 메소드 사용)
    StudentScore jane = new StudentScore();
    jane.setEnglish(89);
    jane.setMath(86);
    jane.setScience(100);
    jane.setHistory(35);
    • 장점
      • 인자 의미 파악 용이하다.
      • 점층적 생성자 패턴처럼 여러 생성자 만들 필요가 없다.
    • 단점
      • 객체 일관성(consistency)이 깨진다.
        => 1회의 호출로 객체 생성이 끝나지 않고 생성한 객체에 값을 계속 넣어주고 있다.
      • Setter 메소드가 있으므로 변경 불가능(immutable)한 클래스를 만들 수가 없다.
        => Thread 안전성을 확보하려면 점층적 생성자 패턴보다 많은 일을 해야 한다.
  3. 빌더 패턴
    public class StudentScore {
        private final int english;
        private final int math;
        private final int science;
        private final int history;
    
        public static class Builder {
            /** 필수 인자 **/
            private final int english;
            private final int math;
    
            /** 선택적 인자는 기본값으로 초기화 **/
            private int science = 0;
            private int history = 0;
    
            public Builder(int english, int math) {
                this.english = english;
                this.math = math;
            }
    
            public Builder science(int val) {
                science = val;
                return this;
            }
    
            public Builder history(int val) {
                history = val;
                return this;
            }
    
            public StudentScore build() {
                return new StudentScore(this);
            }
        }
    
        private StudentScore(Builder builder) {
            english = builder.english;
            math = builder.math;
            science = builder.science;
            history = builder.history;
        }
    }
    아래와 같이 두 가지 방법으로 객체 생성이 가능하다.
    StudentScore.Builder builder = new StudentScore.Builder(100, 88);
    builder.science(100);
    builder.history(35);
    StudentScore jane = builder.build();
    StudentScore jane = new StudentScore.Builder(100, 88)
                                        .science(100)
                                        .history(35)
                                        .build();
    • 장점
      • 각 인자가 어떤 의미인지 알기 쉽다.
      • Setter 메소드가 없으므로 변경 불가능 객체를 만들 수 있다.
      • 한 번에 객체를 생성하므로 객체 일관성이 깨지지 않는다.
      • build() 함수가 잘못된 값이 입력되었는지 검증하게 할 수도 있다.

 

 

 

@Builder 어노테이션 사용

@Builder
public class StudentScore {
  private final int english;
  private final int math;
  private final int science;
  private final int history;
}

또한 빌더 패턴을 사용하면 하나의 빌더 객체로 여러 객체를 만드는 것도 가능하다.

아래와 같은 인터페이스를 만들고, 빌더 클래스가 implements 하게 하면 된다.

public interface Builder<T> {
    public T build();
}

 

 

 

*

@Data 어노케이션은 @ToString, @EqualsAndHashCode, @Getter, @Setter, @RequiredArgsConstructor 을
한 번에 사용하는 강력한 어노테이션으로 지양하는 것이 좋다.

@Data 를 사용하면 자동으로 Setter 를 지원하게 되는데 Setter 는 그 의도가 분명하지 않고
객체를 언제든지 변경할 수 있는 상태가 되어 객체의 안전성을 보장받기 힘들기 때문이다.

(참고 : cheese10yun.github.io/lombok/, hochoon-dev.tistory.com/entry/%EB%B9%8C%EB%8D%94-%ED%8C%A8%ED%84%B4Builder-Pattern-%EC%9D%B4%EB%9E%80)

 

 

 

 

 

반응형

'Java' 카테고리의 다른 글

[Java] static 변수와 static 메소드  (0) 2021.02.10
[Java] Enum class  (0) 2021.02.10
[Java] Source Builder  (0) 2021.02.10
[Java] Collection - Iterator  (0) 2021.02.10
[Java] 정규표현식 Pattern, Matcher  (0) 2021.02.10
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/12   »
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
글 보관함