반응형
빌더(Builder) 패턴이란?
GoF 중 생성 패턴에 속하며, 객체를 생성할 때 유용하게 사용하는 디자인패턴이다.
기존에 생성자를 이용하여 객체를 생성하는데 생길 수 있는 문제를 보완하기 위해 사용되어 지며, 객체의 Optional한 속성이 많을수록 빌더패턴이 더욱 유용해진다.
아래와 같은 스타일로 객체를 생성하는 코드가 있다면, 빌더 패턴을 사용했다고 할 수 있다.
Member member = Member.builder()
.name("홍길동")
.age(30)
.build();
.으로 연속되게 이어지는 패턴을 Dot(.) Chain 문법이라고 부른다.
빌더 패턴의 구조
Builder
- 객체를 생성하는데 사용되는 인터페이스이다.
ConcreteBuilder
- Builder를 실제로 구현하여 객체를 생성까지 담당하는 클래스이다.
Director
- ConcreteBuilder를 파라미터로 받아 디테일한 객체를 생성하고 반환해주는 클래스이다.
예제
Builder - PersonBuilder
public interface PersonBuilder {
public PersonBuilder firstName(String firstName) ;
public PersonBuilder lastName(String lastName) ;
public PersonBuilder birthDate(LocalDate birthDate) ;
public PersonBuilder address(String address) ;
public PersonBuilder sex(String sex) ;
public Person build();
}
ConcreteBuilder - DefaultPersonBuilder
public class DefaultPersonBuilder implements PersonBuilder{
private String firstName;
private String lastName;
private LocalDate birthDate;
private String address;
private String sex;
public DefaultPersonBuilder firstName(String firstName) {
this.firstName = firstName;
return this;
}
public DefaultPersonBuilder lastName(String lastName) {
this.lastName = lastName;
return this;
}
public DefaultPersonBuilder birthDate(LocalDate birthDate) {
this.birthDate = birthDate;
return this;
}
public DefaultPersonBuilder address(String address) {
this.address = address;
return this;
}
public DefaultPersonBuilder sex(String sex) {
this.sex = sex;
return this;
}
public Person build() {
Person person = new Person();
person.setFirstName(firstName);
person.setLastName(lastName);
person.setBirthDate(birthDate);
person.setAddress(address);
person.setSex(sex);
return person;
}
}
Director - PersonDirector
public class PersonDirector {
private PersonBuilder personBuilder;
public PersonDirector (PersonBuilder personBuilder) {
this.personBuilder = personBuilder;
}
public Person teacher() {
return personBuilder
.firstName("최")
.lastName("길동")
.birthDate(LocalDate.of(1977, Month.AUGUST, 21))
.address("서울시 관악구")
.build();
}
}
Main
public class Main {
public static void main(String[] args) {
Person student = Person.builder()
.firstName("홍")
.lastName("길동")
.address("서울시 관악구")
.birthDate(LocalDate.of(1997, Month.AUGUST, 21))
.sex("Male")
.build();
PersonDirector director = new PersonDirector(new DefaultPersonBuilder());
Person teacher = director.teacher();
System.out.println("학생 : " + student.toString());
System.out.println("선생님 : " + teacher.toString());
}
}
결과
빌더패턴을 통해 객체를 유연하고 불변하게 생성하는 것을 확인할 수 있었다.
단일 객체를 다룰 때 Builder 인터페이스와 Director의 경우 불필요하게 코드량이 늘어나기 때문에 사용을 배제하기도 한다.
장점 / 단점
장점
- Setter를 사용하지 않기 때문에 한번의 함수 호출로 불변성을 유지한 객체를 생성할 수 있다.
- 코드의 가독성과 유지보수성이 향상된다.
- 유연성을 확보할 수 있다.
단점
- 객체 수정이 불가능하기 때문에, 필요에 따라 새로운 객체를 계속 생성해야한다.
실사용 사례
- Java.net.http
HttpRequest
String url = "https://api.upbit.com/v1/candles/minutes/";
String param = minute + "?market=" + market + "&count=" + targetCount;
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url + param))
.header("Accept", "application/json")
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
본인이 과거에 upbit api를 사용하기 위해 구현한 소스이다. 이렇듯 Builder 패턴은 특정 객체를 생성하기 위해 다양하게 활용되어 지고 있다.
오늘은 여기까지,,
끗!
반응형
'DesignPattern' 카테고리의 다른 글
Spring Bean을 이용한 팩토리 메서드 패턴으로 객체 분리하기 (1) | 2024.04.07 |
---|---|
[디자인패턴] Flyweight Pattern / 플라이웨이트 패턴 구현 (0) | 2022.09.07 |
댓글