복잡한 객체를 단계별로 구성할 수 있다. 동일한 구성의 코드로 객체의 다양한 유형과 표현을 생성할 수 있다.
사용처
장점
단점
구현
Builder : 모든 유형의 빌더에 공통적인 구성단계 선언
Concreate Builder : Builder의 다양한 구현을 제공, 공통 인터페이스를 따르지 않는 제품 생산 가능
Product : 결과 객체. 다른 빌더에 의해 생성된 객체는 동일한 클래스 계층 또는 인터페이스에 속할 필요가 없다.
Director : 구성 단계를 호출하는 순서를 정의한다. 재사용 가능
Client : 빌더 객체중 하나와 Director를 연결해야 한다. 보통은 생성자 주입을 통해 한 번만 수행되지만, 특별한 상황에서는 매번 다른 빌더를 사용할 수 있다.
코드
Builder
interface Builder {
void reset()
void setRoof()
void setWall()
}
ConcreateBuilder
class HouseBuilder implements Builder {
private House house;
public HouserBuilder() { //생성자에서 초기화
this.reset();
}
public void reset() {
this.house = new House();
}
public void setRoof(...) {
//지붕 구현
}
public void setWall(...) {
//벽 구현
}
public House getProduct() {
product = this.house;
this.reset()
return product;
}
Director
class Director {
public constructHouse(Builder builder) {
builder.reset();
builder.setRoof(...);
builder.setwall(...);
}
public constructVilla(Builder builder) {
...
}
Client
class Main {
void makeHouse() {
Director director = new Director();
HouseBuilder builder = new HouserBuilder();
director.constructHouse(builder);
House house = builder.getProduct();
VillaBuilder builder = new VillaBuilder()
director.constructHouse(builder);
}
이 방법 외에도 ConcreateBuilder에서 메서드 체이닝 방식으로 만들어도 된다.
메서드 체이닝, 롬복 방식을 사용하는 예제를 다루는 블로그를 참고하자
빌더 패턴은 복잡한 객체를 단계별로 구성하는데 중점을 둔다.
추상 팩토리와 구성은 비슷하지만 비슷한 객체군을 생성하는 추상 팩토리와 목적이 다르다.
빌더 패턴은 싱글톤으로 구현할 수 있다.