티스토리 뷰
반응형
Builder 패턴이란, 객체를 생성할 때 사용하는 패턴을 의미한다.
Person person = Person.build()
.name("Jane")
.age(30)
.build();
객체 생성 패턴 3가지
- 점층적 생성자 패턴
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("제인")으로 대체할 수 있다.
- new Person("제인", "국가 비공개", "취미 비공개") 같은 호출이 빈번하게 일어난다면,
- 단점
- 생성자가 많으므로, 인자가 추가되는 일이 발생하면 코드 수정 다소 복잡해진다.
- 인자수가 많을 때 호출 코드만 봐서는 의미를 알기 어렵다.
- 장점
- 자바빈 패턴 (Setter 메소드 사용)
StudentScore jane = new StudentScore(); jane.setEnglish(89); jane.setMath(86); jane.setScience(100); jane.setHistory(35);
- 장점
- 인자 의미 파악 용이하다.
- 점층적 생성자 패턴처럼 여러 생성자 만들 필요가 없다.
- 단점
- 객체 일관성(consistency)이 깨진다.
=> 1회의 호출로 객체 생성이 끝나지 않고 생성한 객체에 값을 계속 넣어주고 있다. - Setter 메소드가 있으므로 변경 불가능(immutable)한 클래스를 만들 수가 없다.
=> Thread 안전성을 확보하려면 점층적 생성자 패턴보다 많은 일을 해야 한다.
- 객체 일관성(consistency)이 깨진다.
- 장점
- 빌더 패턴
아래와 같이 두 가지 방법으로 객체 생성이 가능하다.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 |