생성 디자인 패턴 - 빌더 본문
반응형
빌더 패턴 (Builder)
- 빌더는 복잡한 객체들을 단계별로 생성할 수 있도록 하는 생성 디자인 패턴입니다. 이 패턴을 사용하면 같은 제작 코드를 사용하여 객체의 다양한 유형들과 표현을 제작할 수 있습니다.
- 빌더 패턴을 사용하는 것은 제품에 매우 복잡하고 광범위한 설정이 필요한 경우에만 의미가 있습니다.
점층적 생성자의 제거
class Pizza {
Pizza(int size) { ... }
Pizza(int size, boolean cheese) { ... }
Pizza(int size, boolean cheese, boolean pepperoni) { ... }
// …
- 위의 코드는 여러개의 생성자를 오버로딩하여 객체 생성시, 입맛에 맞는 피자를 만드는 코드입니다.
- 이렇게 생성자를 오버로딩하면 생성자가 길고 복잡해집니다. 이런 상황에서 빌더패턴을 적용해 볼 수 있습니다.
- 빌더패턴은 이러한 피자 클래스로부터 생성자(생성)코드를 추출하여 빌더클래스로 옮기라고 제안합니다.
빌더 구성요소
- 빌더 인터페이스 : 객체(제품)를 만드는데 필요한 과정들을 미리 정의합니다.
- 구상 빌더 클래스 : 특정 제품들을 만드는데 필요한 과정을 구현합니다.
- 디렉터 클래스 : 빌더 클래스와 상호작용하여서 특정 제품(특정 과정생략 또는 추가)을 만듭니다.
- 클라이언트 코드 with director : 디렉터 클래스가 사전에 정의해 놓은 제품들을 생산하는 메서드를 호출하여 간결한 코드로 제품들을 생산합니다.
- 클라이언트 코드 without director : 빌더 클래스에 있는 제품들을 만드는 과정들을 호출하여 제품들을 생산합니다.
요약
- 빌더는 생성패턴이며, 객체를 생성하는데 사용자의 입맛에 맞게 순서나 과정을 조작하여 객체를 만들 수 있습니다.
- 디렉터는 필수요소는 아닙니다. 필요에 따라 선언하고 사용할 수 있고, 간편하게 제품을 만들 수 있다는 장점이 있습니다.
- 디렉터를 사용하지 않는 빌더패턴은 과정의 추가나 순서의 변경을 유동적으로 할 수 있어 수공업의 느낌입니다.
- 디렉터를 사용하면 클라이언트는 디렉터가 정의해놓은 순서나 과정으로 항상 같은 제품을 얻을 수 있기 때문에 공장의 느낌이 납니다.
- 물론 디렉터에서도 빌더를 이용해서 디렉터를 사용하지 않을 때 처럼 조립할 수 있습니다.
반응형
코드
interface PizzaBuilder {
baconTopping(): void;
broccoliTopping(): void;
shrimpTopping(): void;
}
class SweetPotatoPizzaBuilder implements PizzaBuilder {
private pizza: SweetPotatoPizza;
constructor() {
this.reset();
}
public reset(): void {
this.pizza = new SweetPotatoPizza();
}
public baconTopping(): void {
this.pizza.toppings.push('bacon');
}
public broccoliTopping(): void {
this.pizza.toppings.push('broccoli');
}
public shrimpTopping(): void {
this.pizza.toppings.push('shrimp');
}
public getProduct(): SweetPotatoPizza {
const result = this.pizza;
// 리셋을 호출하면 제품을 다 만들고 나서 새로운 피자를 만들 수 있게 됩니다. (초기화)
// 그러나 이것은 선택사항이고, 제품을 다 만들고 reset을 호출하지 않고 제품의 결과를 갖고 있을 수 있습니다.
this.reset();
return result;
}
}
class SweetPotatoPizza {
public toppings: string[] = [];
// 각각 제품들의 특징을 보여주기
public listToppings(): void {
console.log(`toppings : ${this.toppings.join(', ')}\n`);
}
}
class PizzaDirector {
private builder: PizzaBuilder;
// 빌더 하나와 상호작용 하면서 제품 생산
public setBuilder(builder: PizzaBuilder): void {
this.builder = builder;
}
// 베이컨 토핑만 추가하는 피자 제작
public onlyBaconTopping(): void {
this.builder.baconTopping();
}
// 모든 토핑이 들어간 피자 제작
public allToppings(): void {
this.builder.baconTopping();
this.builder.broccoliTopping();
this.builder.shrimpTopping();
}
}
function 피자디렉터이용(director: PizzaDirector) {
const pizzaBuilder = new SweetPotatoPizzaBuilder();
director.setBuilder(pizzaBuilder);
console.log('베이컨 토핑');
director.onlyBaconTopping();
pizzaBuilder.getProduct().listToppings();
console.log('모든토핑 첨가');
director.allToppings();
pizzaBuilder.getProduct().listToppings();
console.log('브로콜리 피자');
pizzaBuilder.broccoliTopping();
pizzaBuilder.getProduct().listToppings();
}
const pizzaDirector = new PizzaDirector();
피자디렉터이용(pizzaDirector);
const 브로콜리빼주세요 = () => {
const pizzaBuilder = new SweetPotatoPizzaBuilder();
console.log('(커스텀 피자 - 빌더로 조립) custom pizza : ');
pizzaBuilder.baconTopping();
pizzaBuilder.shrimpTopping();
pizzaBuilder.getProduct().listToppings();
}
브로콜리빼주세요();
결과
출처
반응형
'OOP 디자인 패턴 > 생성패턴' 카테고리의 다른 글
생성 디자인 패턴 - 싱글턴 (0) | 2023.05.23 |
---|---|
생성 디자인 패턴 - 프로토타입 (0) | 2023.05.19 |
생성 디자인 패턴 - 추상 팩토리 (0) | 2023.04.30 |
생성 디자인 패턴 - 팩토리 메서드 (0) | 2023.04.22 |
Comments