# 빌더 (Builder) 패턴
# 빌더 패턴이란 무엇인가요?
복잡한 객체를 생성하는 방법을 정의하는 클래스와 표현하는 방법을 정의하는 클래스를 별도로 분리하여, 서로 다른 표현이라도 이를 생성할 수 있는 동일한 절차를 제공하는 패턴입니다.
# 예시 코드
public class Character { // 클래스 정의
private String name; // 닉네임
private int level; // 레벨
private String guild; // 길드
private String spouse; // 배우자
public Character(String name, int level, String guild, String spouse) {
this.name = name;
this.level = level;
this.guild = guild;
this.spouse = spouse;
}
}
이렇게 클래스를 정의하면, 인스턴스를 생성할 때 데이터 값이 없을 경우에도 매개변수로 null 값을 다 입력해 주어야 합니다.
Character character = new Character("예시1", 140, null, null) // 인스턴스 생성
하지만, 빌더패턴을 사용한다면
public class Character { // 클래스 정의
private String name; // 닉네임
private int level; // 레벨
private String guild; // 길드
private String spouse; // 배우자
private Character(Builder builder) {
this.name = builder.name;
this.level = builder.level;
this.guild = builder.guild;
this.spouse = builder.spouse;
}
public static class CharacterBuilder { // 정적 내부 클래스
private String name;
private int level;
private String guild;
private String spouse;
public CharacterBuilder() {} // 현재 예시에서는 생성자 부분을 비워놨지만, 이 부분에 필수로 입력해야하는 필드를 집어넣어도 된다.
public CharacterBuilder name(String name) {
this.name = name;
return this;
}
public CharacterBuilder level(int level) {
this.level = level;
return this;
}
... //guild와 spouse도 비슷하게 생성
public Character build() {
return new Character(this);
}
}
}
Character character = new Character.CharacterBuilder()
.name("예시2")
.level(200)
.guild("빌더패턴")
.build();
이런식으로 필요한 데이터값만을 입력하여 인스턴스를 생성할 수 있습니다.
# 생성자 대신에 Setter을 이용하면 빌더패턴을 안써도 되지 않나요?
setter을 사용한다면, 인스턴스의 생성후에도 setter을 이용하여 데이터의 값이 변경될 가능성이 있습니다. 하지만 빌더패턴을 사용한다면 인스턴스의 생성후에 데이터의 값이 변화될 수 없어 안전하고 유지보수에 더 용이합니다.
# 빌더 패턴을 사용하는 경우
- 매개변수가 많거나 선택 인자가 많을 때 사용하는 것이 좋습니다.
# 빌더 패턴을 사용한 예시
- java.lang.StringBuilder, StringBuffer
- 롬복 라이브러리의 @Builder
- 스프링의 MockMvcWebClientBuilder
# 빌더 패턴의 장점은 무엇인가요?
- 필요한 데이터만 값을 설정할 수 있어, 테스트를 할 때 용이하고 불필요한 코드의 양을 줄어줍니다.
- 유연성이 좋아서 새로운 기능을 추가하기 편리합니다.
- 데이터에 어떤 값이 설정되는지 직관적으로 볼 수 있어, 매개변수가 많아도 가독성이 높습니다.
- 객체를 할당할 때만 값을 설정할 수 있어, 변경 가능성을 최소화할 수 있습니다.
# 빌더 패턴의 단점은 무엇인가요?
- 객체를 생성하려면 Builder 객체를 만들어야하기 때문에, 생성자를 사용하는 것에 비해 코드가 복잡해집니다.
# 참고자료
출처: https://mangkyu.tistory.com/163 [망나니개발자]
출처: https://www.jiniaslog.co.kr/article/view?articleId=702 [Jinia's LOG]