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

== 구조 ==
[[파일:Builder UML class diagram.svg|700px]]
== 예 ==

=== 자바 ===
<syntaxhighlight lang="java">
/** "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();
	}
}

</syntaxhighlight>

=== C# ===
<syntaxhighlight lang="csharp">
//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();
    }
}

</syntaxhighlight>

=== C++ ===
<syntaxhighlight lang="cpp">
// 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;
}
</syntaxhighlight>

=== [[비주얼 프롤로그]] ===
Product

 <span style="color:#808000;">interface</span> pizza
    <span style="color:#808000;">predicates</span>
       setDough : <span style="color:#993300;">(</span>string <span style="color:#008000;">Dough</span><span style="color:#993300;">)</span>.
       setSauce : <span style="color:#993300;">(</span>string <span style="color:#008000;">Sauce</span><span style="color:#993300;">)</span>.
       setTopping : <span style="color:#993300;">(</span>string <span style="color:#008000;">Topping</span><span style="color:#993300;">)</span>.
 <span style="color:#808000;">end</span> <span style="color:#808000;">interface</span> pizza

 <span style="color:#808000;">class</span> pizza : pizza
 <span style="color:#808000;">end</span> <span style="color:#808000;">class</span> pizza

 <span style="color:#808000;">implement</span> pizza
    <span style="color:#808000;">facts</span>
       dough : string := <span style="color:#0000FF;">""</span>.
       sauce : string := <span style="color:#0000FF;">""</span>.
       topping : string := <span style="color:#0000FF;">""</span>.
    <span style="color:#808000;">clauses</span>
       setDough<span style="color:#993300;">(</span><span style="color:#008000;">Dough</span><span style="color:#993300;">)</span> :- dough := <span style="color:#008000;">Dough</span>.
    <span style="color:#808000;">clauses</span>
       setSauce<span style="color:#993300;">(</span><span style="color:#008000;">Sauce</span><span style="color:#993300;">)</span> :- sauce := <span style="color:#008000;">Sauce</span>.
    <span style="color:#808000;">clauses</span>
       setTopping<span style="color:#993300;">(</span><span style="color:#008000;">Topping</span><span style="color:#993300;">)</span> :- topping := <span style="color:#008000;">Topping</span>.
 <span style="color:#808000;">end</span> <span style="color:#808000;">implement</span> pizza

Abstract Builder

 <span style="color:#808000;">interface</span> pizzaBuilder
    <span style="color:#808000;">predicates</span>
       getPizza : <span style="color:#993300;">()</span> -&gt; pizza <span style="color:#008000;">Pizza</span>.
       createNewPizzaProduct : <span style="color:#993300;">()</span>.
    <span style="color:#808000;">predicates</span>
       buildDough : <span style="color:#993300;">()</span>.
       buildSauce : <span style="color:#993300;">()</span>.
       buildTopping : <span style="color:#993300;">()</span>.
 <span style="color:#808000;">end</span> <span style="color:#808000;">interface</span> pizzaBuilder

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

 <span style="color:#808000;">interface</span> pizzaBuilderSupport
    <span style="color:#808000;">predicates</span> <span style="color:#333399;">from</span> pizzaBuilder
       getPizza, createNewPizzaProduct
 <span style="color:#808000;">end</span> <span style="color:#808000;">interface</span> pizzaBuilderSupport

 <span style="color:#808000;">class</span> pizzaBuilderSupport : pizzaBuilderSupport
 <span style="color:#808000;">end</span> <span style="color:#808000;">class</span> pizzaBuilderSupport

 <span style="color:#808000;">implement</span> pizzaBuilderSupport
    <span style="color:#808000;">facts</span>
       pizza : pizza := <span style="color:#333399;">erroneous</span>.
    <span style="color:#808000;">clauses</span>
       getPizza<span style="color:#993300;">()</span> = pizza.
    <span style="color:#808000;">clauses</span>
       createNewPizzaProduct<span style="color:#993300;">()</span> :- pizza := pizza::new<span style="color:#993300;">()</span>.
 <span style="color:#808000;">end</span> <span style="color:#808000;">implement</span> pizzaBuilderSupport

ConcreteBuilder #1

 <span style="color:#808000;">class</span> hawaiianPizzaBuilder :  pizzaBuilder
 <span style="color:#808000;">end</span> <span style="color:#808000;">class</span> hawaiianPizzaBuilder

 <span style="color:#808000;">implement</span> hawaiianPizzaBuilder
    <span style="color:#808000;">inherits</span> pizzaBuilderSupport

    <span style="color:#808000;">clauses</span>
       buildDough<span style="color:#993300;">()</span> :- getPizza<span style="color:#993300;">()</span>:setDough<span style="color:#993300;">(</span><span style="color:#0000FF;">"cross"</span><span style="color:#993300;">)</span>.
    <span style="color:#808000;">clauses</span>
       buildSauce<span style="color:#993300;">()</span> :- getPizza<span style="color:#993300;">()</span>:setSauce<span style="color:#993300;">(</span><span style="color:#0000FF;">"mild"</span><span style="color:#993300;">)</span>.
    <span style="color:#808000;">clauses</span>
       buildTopping<span style="color:#993300;">()</span> :- getPizza<span style="color:#993300;">()</span>:setTopping<span style="color:#993300;">(</span><span style="color:#0000FF;">"ham+pineapple"</span><span style="color:#993300;">)</span>.
 <span style="color:#808000;">end</span> <span style="color:#808000;">implement</span> hawaiianPizzaBuilder

ConcreteBuilder #2

 <span style="color:#808000;">class</span> spicyPizzaBuilder :  pizzaBuilder
 <span style="color:#808000;">end</span> <span style="color:#808000;">class</span> spicyPizzaBuilder

 <span style="color:#808000;">implement</span> spicyPizzaBuilder
    <span style="color:#808000;">inherits</span> pizzaBuilderSupport

    <span style="color:#808000;">clauses</span>
       buildDough<span style="color:#993300;">()</span> :- getPizza<span style="color:#993300;">()</span>:setDough<span style="color:#993300;">(</span><span style="color:#0000FF;">"pan baked"</span><span style="color:#993300;">)</span>.
    <span style="color:#808000;">clauses</span>
       buildSauce<span style="color:#993300;">()</span> :- getPizza<span style="color:#993300;">()</span>:setSauce<span style="color:#993300;">(</span><span style="color:#0000FF;">"hot"</span><span style="color:#993300;">)</span>.
    <span style="color:#808000;">clauses</span>
       buildTopping<span style="color:#993300;">()</span> :- getPizza<span style="color:#993300;">()</span>:setTopping<span style="color:#993300;">(</span><span style="color:#0000FF;">"pepperoni+salami"</span><span style="color:#993300;">)</span>.
 <span style="color:#808000;">end</span> <span style="color:#808000;">implement</span> spicyPizzaBuilder

Director

 <span style="color:#808000;">interface</span> waiter
    <span style="color:#808000;">predicates</span>
       setPizzaBuilder : <span style="color:#993300;">(</span>pizzaBuilder <span style="color:#008000;">PizzaBuilder</span><span style="color:#993300;">)</span>.
       getPizza : <span style="color:#993300;">()</span> -&gt; pizza <span style="color:#008000;">Pizza</span>.
    <span style="color:#808000;">predicates</span>
       constructPizza : <span style="color:#993300;">()</span>.
 <span style="color:#808000;">end</span> <span style="color:#808000;">interface</span> waiter

 <span style="color:#808000;">class</span> waiter : waiter
 <span style="color:#808000;">end</span> <span style="color:#808000;">class</span> waiter

 <span style="color:#808000;">implement</span> waiter
    <span style="color:#808000;">facts</span>
       pizzaBuilder : pizzaBuilder := <span style="color:#333399;">erroneous</span>.
    <span style="color:#808000;">clauses</span>
       setPizzaBuilder<span style="color:#993300;">(</span><span style="color:#008000;">PizzaBuilder</span><span style="color:#993300;">)</span> :- pizzaBuilder := <span style="color:#008000;">PizzaBuilder</span>.
    <span style="color:#808000;">clauses</span>
       getPizza<span style="color:#993300;">()</span> = pizzaBuilder:getPizza<span style="color:#993300;">()</span>.
    <span style="color:#808000;">clauses</span>
       constructPizza<span style="color:#993300;">()</span> :- 
          pizzaBuilder:createNewPizzaProduct<span style="color:#993300;">()</span>,
          pizzaBuilder:buildDough<span style="color:#993300;">()</span>,
          pizzaBuilder:buildSauce<span style="color:#993300;">()</span>,
          pizzaBuilder:buildTopping<span style="color:#993300;">()</span>.
 <span style="color:#808000;">end</span> <span style="color:#808000;">implement</span> waiter

A customer ordering a pizza.

 <span style="color:#808000;">goal</span>
    <span style="color:#008000;">Hawaiian_pizzabuilder</span> = hawaiianPizzaBuilder::new<span style="color:#993300;">()</span>,
    <span style="color:#008000;">Waiter</span> = waiter::new<span style="color:#993300;">()</span>,
    <span style="color:#008000;">Waiter</span>:setPizzaBuilder<span style="color:#993300;">(</span><span style="color:#008000;">Hawaiian_pizzabuilder</span><span style="color:#993300;">)</span>,
    <span style="color:#008000;">Waiter</span>:constructPizza<span style="color:#993300;">()</span>,
    <span style="color:#008000;">Pizza</span> = <span style="color:#008000;">Waiter</span>:getPizza<span style="color:#993300;">()</span>.

=== 펄 ===
<syntaxhighlight lang="perl">
## 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;
</syntaxhighlight>


=== PHP ===
<syntaxhighlight lang="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);
</syntaxhighlight>
== 같이 보기 ==
* [[커링]]

{{디자인 패턴(소프트웨어)}}

[[분류:소프트웨어 디자인 패턴]]