빌더 패턴이란 복합 객체의 생성 과정과 표현 방법을 분리하여 동일한 생성 절차에서 서로 다른 표현 결과를 만들 수 있게 하는 패턴이다. **2 단어 요약 : 생성자 오버로딩**

구조
--

예
-

### 자바

```
/\*\* "Product" \*/
class Pizza {
 private String dough = "";
 private String sauce = "";
 private String topping = "";

 public void setDough(String dough) {
 this.dough = dough;
 }

 public void setSauce(String sauce) {
 this.sauce = sauce;
 }

 public void setTopping(String topping) {
 this.topping = topping;
 }
}

/\*\* "Abstract Builder" \*/
abstract class PizzaBuilder {
 protected Pizza pizza;

 public Pizza getPizza() {
 return pizza;
 }

 public void createNewPizzaProduct() {
 pizza = new Pizza();
 }

 public abstract void buildDough();

 public abstract void buildSauce();

 public abstract void buildTopping();
}

/\*\* "ConcreteBuilder" \*/
class HawaiianPizzaBuilder extends PizzaBuilder {
 public void buildDough() {
 pizza.setDough("cross");
 }

 public void buildSauce() {
 pizza.setSauce("mild");
 }

 public void buildTopping() {
 pizza.setTopping("ham+pineapple");
 }
}

/\*\* "ConcreteBuilder" \*/
class SpicyPizzaBuilder extends PizzaBuilder {
 public void buildDough() {
 pizza.setDough("pan baked");
 }

 public void buildSauce() {
 pizza.setSauce("hot");
 }

 public void buildTopping() {
 pizza.setTopping("pepperoni+salami");
 }
}

/\*\* "Director" \*/
class Cook {
 private PizzaBuilder pizzaBuilder;

 public void setPizzaBuilder(PizzaBuilder pizzaBuilder) {
 this.pizzaBuilder = pizzaBuilder;
 }

 public Pizza getPizza() {
 return pizzaBuilder.getPizza();
 }

 public void constructPizza() {
 pizzaBuilder.createNewPizzaProduct();
 pizzaBuilder.buildDough();
 pizzaBuilder.buildSauce();
 pizzaBuilder.buildTopping();
 }
}

/\*\* A given type of pizza being constructed. \*/
public class BuilderExample {
 public static void main(String[] args) {
 Cook cook = new Cook();
 PizzaBuilder hawaiianPizzaBuilder = new HawaiianPizzaBuilder();
 PizzaBuilder spicyPizzaBuilder = new SpicyPizzaBuilder();

 cook.setPizzaBuilder(hawaiianPizzaBuilder);
 cook.constructPizza();

 Pizza pizza = cook.getPizza();
 }
}

```

### C#

```
//Implementation in C#.
class Pizza
{
 string dough;
 string sauce;
 string topping;
 public Pizza() {}
 public void SetDough( string d){ dough = d;}
 public void SetSauce( string s){ sauce = s;}
 public void SetTopping( string t){ topping = t;}
}

//Abstract Builder
abstract class PizzaBuilder
{
 protected Pizza pizza;
 public PizzaBuilder(){}
 public Pizza GetPizza(){ return pizza; }
 public void CreateNewPizza() { pizza = new Pizza(); }

 public abstract void BuildDough();
 public abstract void BuildSauce();
 public abstract void BuildTopping();
}

//Concrete Builder
class HawaiianPizzaBuilder : PizzaBuilder
{
 public override void BuildDough() { pizza.SetDough("cross"); }
 public override void BuildSauce() { pizza.SetSauce("mild"); }
 public override void BuildTopping() { pizza.SetTopping("ham+pineapple"); }
}

//Concrete Builder
class SpicyPizzaBuilder : PizzaBuilder
{
 public override void BuildDough() { pizza.SetDough("pan baked"); }
 public override void BuildSauce() { pizza.SetSauce("hot"); }
 public override void BuildTopping() { pizza.SetTopping("pepparoni+salami"); }
}

/\*\* "Director" \*/
class Waiter {
 private PizzaBuilder pizzaBuilder;

 public void SetPizzaBuilder (PizzaBuilder pb) { pizzaBuilder = pb; }
 public Pizza GetPizza() { return pizzaBuilder.GetPizza(); }

 public void ConstructPizza() {
 pizzaBuilder.CreateNewPizza();
 pizzaBuilder.BuildDough();
 pizzaBuilder.BuildSauce();
 pizzaBuilder.BuildTopping();
 }
}

/\*\* A customer ordering a pizza. \*/
class BuilderExample
{
 public static void Main(string[] args) {
 Waiter waiter = new Waiter();
 PizzaBuilder hawaiianPizzaBuilder = new HawaiianPizzaBuilder();
 PizzaBuilder spicyPizzaBuilder = new SpicyPizzaBuilder();

 waiter.SetPizzaBuilder ( hawaiianPizzaBuilder );
 waiter.ConstructPizza();

 Pizza pizza = waiter.GetPizza();
 }
}

```

### C++

```
// Implementation in C++.

#include <iostream>
#include <memory>
#include <string>

// Product
class Pizza
{
private:
 std::string dough;
 std::string sauce;
 std::string topping;

public:
 Pizza() { }
 ~Pizza() { }

 void SetDough(const std::string& d) { dough = d; };
 void SetSauce(const std::string& s) { sauce = s; };
 void SetTopping(const std::string& t) { topping = t; }

 void ShowPizza()
 {
 std::cout << "Yummy !!!" << std::endl
 << "Pizza with Dough as "<< dough
 << ", Sauce as "<< sauce
 << "and Topping as "<< topping
 << "!!! "<< std::endl;
 }
};

// Abstract Builder
class PizzaBuilder
{
protected:
 std::auto\_ptr<Pizza> pizza;
public:
 PizzaBuilder() {}
 virtual ~PizzaBuilder() {}
 std::auto\_ptr<Pizza> GetPizza() { return pizza; }

 void createNewPizzaProduct() { pizza.reset (new Pizza); }

 virtual void buildDough()=0;
 virtual void buildSauce()=0;
 virtual void buildTopping()=0;
};

// ConcreteBuilder
class HawaiianPizzaBuilder : public PizzaBuilder
{
public:
 HawaiianPizzaBuilder() : PizzaBuilder() {}
 ~HawaiianPizzaBuilder(){}

 void buildDough() { pizza->SetDough("cross"); }
 void buildSauce() { pizza->SetSauce("mild"); }
 void buildTopping() { pizza->SetTopping("ham and pineapple"); }
};

// ConcreteBuilder
class SpicyPizzaBuilder : public PizzaBuilder
{
public:
 SpicyPizzaBuilder() : PizzaBuilder() {}
 ~SpicyPizzaBuilder() {}

 void buildDough() { pizza->SetDough("pan baked"); }
 void buildSauce() { pizza->SetSauce("hot"); }
 void buildTopping() { pizza->SetTopping("pepperoni and salami"); }
};

// Director
class Waiter
{
private:
 PizzaBuilder\* pizzaBuilder;
public:
 Waiter() : pizzaBuilder(NULL) {}
 ~Waiter() { }

 void SetPizzaBuilder(PizzaBuilder\* b) { pizzaBuilder = b; }
 std::auto\_ptr<Pizza> GetPizza() { return pizzaBuilder->GetPizza(); }
 void ConstructPizza()
 {
 pizzaBuilder->createNewPizzaProduct();
 pizzaBuilder->buildDough();
 pizzaBuilder->buildSauce();
 pizzaBuilder->buildTopping();
 }
};

// A customer ordering a pizza.
int main()
{
 Waiter waiter;

 HawaiianPizzaBuilder hawaiianPizzaBuilder;
 waiter.SetPizzaBuilder (&hawaiianPizzaBuilder);
 waiter.ConstructPizza();
 std::auto\_ptr<Pizza> pizza = waiter.GetPizza();
 pizza->ShowPizza();

 SpicyPizzaBuilder spicyPizzaBuilder;
 waiter.SetPizzaBuilder(&spicyPizzaBuilder);
 waiter.ConstructPizza();
 pizza = waiter.GetPizza();
 pizza->ShowPizza();

 return EXIT\_SUCCESS;
}

```

### 비주얼 프롤로그

Product

```
interface pizza
   predicates
      setDough : (string Dough).
      setSauce : (string Sauce).
      setTopping : (string Topping).
end interface pizza
```

```
class pizza : pizza
end class pizza
```

```
implement pizza
   facts
      dough : string := "".
      sauce : string := "".
      topping : string := "".
   clauses
      setDough(Dough) :- dough := Dough.
   clauses
      setSauce(Sauce) :- sauce := Sauce.
   clauses
      setTopping(Topping) :- topping := Topping.
end implement pizza
```

Abstract Builder

```
interface pizzaBuilder
   predicates
      getPizza : () -> pizza Pizza.
      createNewPizzaProduct : ().
   predicates
      buildDough : ().
      buildSauce : ().
      buildTopping : ().
end interface pizzaBuilder
```

Visual Prolog does not support abstract classes, but we can create a support class instead:

```
interface pizzaBuilderSupport
   predicates from pizzaBuilder
      getPizza, createNewPizzaProduct
end interface pizzaBuilderSupport
```

```
class pizzaBuilderSupport : pizzaBuilderSupport
end class pizzaBuilderSupport
```

```
implement pizzaBuilderSupport
   facts
      pizza : pizza := erroneous.
   clauses
      getPizza() = pizza.
   clauses
      createNewPizzaProduct() :- pizza := pizza::new().
end implement pizzaBuilderSupport
```

ConcreteBuilder #1

```
class hawaiianPizzaBuilder :  pizzaBuilder
end class hawaiianPizzaBuilder
```

```
implement hawaiianPizzaBuilder
   inherits pizzaBuilderSupport
```

```
   clauses
      buildDough() :- getPizza():setDough("cross").
   clauses
      buildSauce() :- getPizza():setSauce("mild").
   clauses
      buildTopping() :- getPizza():setTopping("ham+pineapple").
end implement hawaiianPizzaBuilder
```

ConcreteBuilder #2

```
class spicyPizzaBuilder :  pizzaBuilder
end class spicyPizzaBuilder
```

```
implement spicyPizzaBuilder
   inherits pizzaBuilderSupport
```

```
   clauses
      buildDough() :- getPizza():setDough("pan baked").
   clauses
      buildSauce() :- getPizza():setSauce("hot").
   clauses
      buildTopping() :- getPizza():setTopping("pepperoni+salami").
end implement spicyPizzaBuilder
```

Director

```
interface waiter
   predicates
      setPizzaBuilder : (pizzaBuilder PizzaBuilder).
      getPizza : () -> pizza Pizza.
   predicates
      constructPizza : ().
end interface waiter
```

```
class waiter : waiter
end class waiter
```

```
implement waiter
   facts
      pizzaBuilder : pizzaBuilder := erroneous.
   clauses
      setPizzaBuilder(PizzaBuilder) :- pizzaBuilder := PizzaBuilder.
   clauses
      getPizza() = pizzaBuilder:getPizza().
   clauses
      constructPizza() :- 
         pizzaBuilder:createNewPizzaProduct(),
         pizzaBuilder:buildDough(),
         pizzaBuilder:buildSauce(),
         pizzaBuilder:buildTopping().
end implement waiter
```

A customer ordering a pizza.

```
goal
   Hawaiian\_pizzabuilder = hawaiianPizzaBuilder::new(),
   Waiter = waiter::new(),
   Waiter:setPizzaBuilder(Hawaiian\_pizzabuilder),
   Waiter:constructPizza(),
   Pizza = Waiter:getPizza().
```

### 펄

```
## Product
package pizza;

sub new {
 return bless {
 dough => undef,
 sauce => undef,
 topping => undef
 }, shift;
}

sub set\_dough {
 my( $self, $dough ) = @\_;
 $self->{dough} = $dough;
}

sub set\_sauce {
 my( $self, $sauce ) = @\_;
 $self->{sauce} = $sauce;
}

sub set\_topping {
 my( $self, $topping ) = @\_;
 $self->{topping} = $topping;
}

1;

## Abstract builder
package pizza\_builder;

sub new {
 return bless {
 pizza => undef
 }, shift;
}

sub get\_pizza {
 my( $self ) = @\_;
 return $self->{pizza};
}

sub create\_new\_pizza\_product {
 my( $self ) = @\_;
 $self->{pizza} = pizza->new;
}

# This is what an abstract method could look like in perl...

sub build\_dough {
 croak("This method must be overridden.");
}

sub build\_sauce {
 croak("This method must be overridden.");
}

sub build\_topping {
 croak("This method must be overridden.");
}

1;

## Concrete builder
package hawaiian\_pizza\_builder;

use base qw{ pizza\_builder };

sub build\_dough {
 my( $self ) = @\_;
 $self->{pizza}->set\_dough("cross");
}

sub build\_sauce {
 my( $self ) = @\_;
 $self->{pizza}->set\_sauce("mild");
}

sub build\_topping {
 my( $self ) = @\_;
 $self->{pizza}->set\_topping("ham+pineapple");
}

1;

## Concrete builder
package spicy\_pizza\_builder;

use base qw{ pizza\_builder };

sub build\_dough {
 my( $self ) = @\_;
 $self->{pizza}->set\_dough("pan baked");
}

sub build\_sauce {
 my( $self ) = @\_;
 $self->{pizza}->set\_sauce("hot");
}

sub build\_topping {
 my( $self ) = @\_;
 $self->{pizza}->set\_topping("pepperoni+salami");
}

1;

## Director
package waiter;

sub new {
 return bless {
 pizza\_builder => undef
 }, shift;
}

sub set\_pizza\_builder {
 my( $self, $builder ) = @\_;
 $self->{pizza\_builder} = $builder;
}

sub get\_pizza {
 my( $self ) = @\_;
 return $self->{pizza\_builder}->get\_pizza;
}

sub construct\_pizza {
 my( $self ) = @\_;
 $self->{pizza\_builder}->create\_new\_pizza\_product;
 $self->{pizza\_builder}->build\_dough;
 $self->{pizza\_builder}->build\_sauce;
 $self->{pizza\_builder}->build\_topping;
}

1;

## Lets order pizza (client of Director/Builder)
package main

my $waiter = waiter->new;
my $hawaiian\_pb = hawaiian\_pizza\_builder->new;
my $spicy\_pb = spicy\_pizza\_builder->new;

$waiter->set\_pizza\_builder( $hawaiian\_pb );
$waiter->construct\_pizza;

my $pizza = $waiter->get\_pizza;

print "Serving a nice pizza with:\n";
for (keys %$pizza) {
 print "$pizza->{$\_} $\_\n";
}

1;

```

  

### PHP

```
/\*\* Product \*\*/
class Pizza{
  private $dough;
  private $sauce;
  private $topping;
  public function setDough($dough){
    $this->dough = $dough;
  }
  public function setSauce($sauce){
    $this->sauce = $sauce;
  }
  public function setTopping($topping){
    $this->topping = $topping;
  }
}

/\*\* Abstract builder \*\*/
abstract class PizzaBuilder{
  protected $pizza;
  public function \_\_construct(){
    $this->pizza = new Pizza();
  }
  public function getPizza(){
    return $this->pizza;
  }
  abstract function buildDough();
  abstract function buildSauce();
  abstract function buildTopping();
}

/\*\* Concrete builder \*\*/
class SpicyPizza extends PizzaBuilder{
  public function buildDough(){
    $this->pizza->setDough('crispy');
  }
  public function buildSauce(){
    $this->pizza->setSauce('hot');
  }
  public function buildTopping(){
    $this->pizza->setTopping('pepperoni+salami');
  }
}

/\*\* Director \*\*/
class Chef{
  private $pizza\_builder;
  public function setPizzaBuilder(PizzaBuilder $pizza\_builder){
    $this->pizza\_builder = $pizza\_builder;
  }
  public function cookPizza(){
    $this->pizza\_builder->buildDough();
    $this->pizza\_builder->buildSauce();
    $this->pizza\_builder->buildTopping();
  }
  public function getPizza(){
    return $this->pizza\_builder->getPizza();
  }
}

//Customer orders a Pizza.
$chef = new Chef();

$order = new SpicyPizza();
$chef->setPizzaBuilder($order);
$chef->cookPizza();
$pizza = $chef->getPizza();

print\_r($pizza);

```

| * v
* t
* e
소프트웨어 디자인 패턴 |
| --- |
| 4인방(Gang of four) 패턴 | 

|  |  |
| --- | --- |
| 생성 패턴 | 
* 추상 팩토리
* 빌더
* 팩토리 메소드
* 프로토타입
* 싱글턴

 |
| 구조 패턴 | 
* 어댑터
* 브리지
* 컴포지트
* 데코레이터
* 퍼사드
* 플라이웨이트
* 프록시

 |
| 동작 패턴 | 
* 책임 연쇄
* 커맨드
* 인터프리터
* 반복자
* 중재자
* 메멘토
* 옵서버
* 상태
* 전략
* 템플릿 메소드
* 비지터

 |

 |
| 동시성 패턴 | 
* 액티브 오브젝트
* Balking
* 바인딩 속성
* 더블 체크 라킹
* 이벤트 기반 비동기
* 가디드 서스펜션
* 조인
* 락
* 모니터 (동기화)
* 프로액터
* 반응자 패턴
* 읽기 쓰기 락
* 스케줄링 (컴퓨팅)
* 스레드 풀
* 스레드 로컬 스토리지

 |
| 아키텍처 패턴 | 
* 프론트 컨트롤러
* 인터셉터
* 모델-뷰-컨트롤러
* 모델-뷰-프리젠터
* 모델-뷰-뷰모델
* 다층 구조
* 사양
* 발행-구독 모델
* 네이키드 오브젝트
* 서비스 로케이터
* 액티브 레코드
* 아이덴티티 맵
* 데이터 접근 객체
* 데이터 전송 객체
* ADR
* 제어 반전

 |
| 기타 패턴 | 
* 블랙보드
* 비즈니스 델리게이트
* 컴포지트 엔티티
* 의존성 주입
* 인터셉터 필터
* 지연된 로딩
* 모의 객체
* 널 객체
* 객체 풀
* 서번트
* 트윈
* 타입 터널
* 메서드 체이닝

 |
| 관련 도서 | 
* 《디자인 패턴》
* 《Enterprise Integration Patterns》

 |
| 인물 | 
* 크리스토퍼 알렉산더
* 에릭 감마
* 랄프 존슨
* John Vlissides
* 그래디 부치
* 켄트 벡
* 워드 커닝햄
* 마틴 파울러
* 로버트 마틴
* Jim Coplien
* 더글라스 슈미트
* 린다 라이징

 |
| 커뮤니티 | 
* 힐사이드 그룹
* 포틀랜드 패턴 리포지토리

 |