Builder Pattern
Builder Pattern
Builder Pattern
- 객체를 생성할때 사용하는 디자인 패턴
- 객체를 생성하는 방법을 정의하는 클래스와 표현하는 법을 정의하는 클래스를 분리
- 별도의 builder 클래스를 통해 메소드를 chaining 형태로 호출해서 필요한 데이터를 순차적으로 입력받음
- 다양한 구성의 인스턴스를 만들 수 있음
구현 방법
public class Test {
private final int id;
private final String name;
private final String addr;
private Test(TestBuilder builder) {
this.id = builder.id;
this.name = builder.name;
this.addr = builder.addr;
}
public static class TestBuilder {
private int id;
private String name = "John doe"; // Default
private String addr = "Chunryang"; // Default
public TestBuilder(int id) {
this.id = id;
}
public TestBuilder name(String name) {
this.name = name;
return this;
}
public TestBuilder addr(String addr) {
this.addr = addr;
return this;
}
public Test build() {
return new Test(this);
}
}
}
Test t = new Test.TestBuilder(3).name("MooHyungSuck").build();
- 클래스에 public한 생성자를 두지 않음
- 클래스 내부에 static class로 별도의 builder 클래스를 생성
- Builder 클래스는 생성자로 반드시 필요한 필드의 데이터를 우선 받음
- Builder 클래스는 메소드를 호출해서 선택 가능한 필드의 데이터를 입력 받음
- chaining 형태로 호출하기 위해 builder 클래스의 각 메소드는
this
를 반환해야 함 - 마지막에
build
메소드를 호출해 클래스의 데이터 생성
장점
- 각 인스턴스에 필요한 데이터만 설정 가능
- 확장에 있어 유연성 확보 가능
- 가독성을 높임
- 값을 할당하는 시점이 객체의 생성 시점이므로, 객체가 변경될 가능성이 있는 setter 함수를 구현하지 않아도 됨
- 변경 가능성 최소화
- Default 매개변수 기능을 간접적으로 설정 가능
단점
- 코드가 복잡하고 길어질 수 있음
- 생성자보다 성능이 떨어짐
- 필드 갯수가 적거나, 변경 가능성이 적은 경우 비효율적일 수 있음
Lombok @Builder
- Lombok의
@Builder
어노테이션을 이용하는 경우, 빌더 패턴 적용 가능 클래스.builder().a().b().c().build()
형식으로 쉽게 사용 가능
References
- https://mangkyu.tistory.com/163
- https://readystory.tistory.com/121
- https://inpa.tistory.com/entry/GOF-%F0%9F%92%A0-%EB%B9%8C%EB%8D%94Builder-%ED%8C%A8%ED%84%B4-%EB%81%9D%ED%8C%90%EC%99%95-%EC%A0%95%EB%A6%AC