빌더 패턴

빌더 패턴이란 복합 객체의 생성 과정과 표현 방법을 분리하여 동일한 생성 절차에서 서로 다른 표현 결과를 만들 수 있게 하는 패턴이다. 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;
//Abstract Builder
abstract class PizzaBuilder
 protected Pizza pizza;
 public abstract void BuildDough();
 public abstract void BuildSauce();
 public abstract void BuildTopping();
//Concrete Builder
class HawaiianPizzaBuilder : PizzaBuilder
//Concrete Builder
class SpicyPizzaBuilder : PizzaBuilder
/** "Director" */
class Waiter {
 private PizzaBuilder pizzaBuilder;
 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++.
// Product
class Pizza
private:
 std::string dough;
 std::string sauce;
 std::string topping;
public:
 void SetDough(const std::string&amp; d) { dough = d; };
 void SetSauce(const std::string&amp; s) { sauce = s; };
 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&lt;Pizza&gt; pizza;
public:
 virtual void buildDough()=0;
 virtual void buildSauce()=0;
 virtual void buildTopping()=0;
// ConcreteBuilder
class HawaiianPizzaBuilder : public PizzaBuilder
public:
// ConcreteBuilder
class SpicyPizzaBuilder : public PizzaBuilder
public:
// Director
class Waiter
private:
 PizzaBuilder* pizzaBuilder;
public:
 void ConstructPizza()
 pizzaBuilder-&gt;createNewPizzaProduct();
 pizzaBuilder-&gt;buildDough();
 pizzaBuilder-&gt;buildSauce();
 pizzaBuilder-&gt;buildTopping();
};
// A customer ordering a pizza.
int main()
 Waiter waiter;
 HawaiianPizzaBuilder hawaiianPizzaBuilder;
 waiter.SetPizzaBuilder (&amp;hawaiianPizzaBuilder);
 waiter.ConstructPizza();
 std::auto_ptr&lt;Pizza&gt; pizza = waiter.GetPizza();
 pizza-&gt;ShowPizza();
 SpicyPizzaBuilder spicyPizzaBuilder;
 waiter.SetPizzaBuilder(&amp;spicyPizzaBuilder);
 waiter.ConstructPizza();
 pizza = waiter.GetPizza();
 pizza-&gt;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 : () -&gt; 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 : () -&gt; 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().
펄.
package pizza;
sub new {
 return bless {
 dough =&gt; undef,
 sauce =&gt; undef,
 topping =&gt; undef
 }, shift;
sub set_dough {
 my( $self, $dough ) = @_;
 $self-&gt;{dough} = $dough;
sub set_sauce {
 my( $self, $sauce ) = @_;
 $self-&gt;{sauce} = $sauce;
sub set_topping {
 my( $self, $topping ) = @_;
 $self-&gt;{topping} = $topping;
1;
package pizza_builder;
sub new {
 return bless {
 pizza =&gt; undef
 }, shift;
sub get_pizza {
 my( $self ) = @_;
 return $self-&gt;{pizza};
sub create_new_pizza_product {
 my( $self ) = @_;
 $self-&gt;{pizza} = pizza-&gt;new;
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;
package hawaiian_pizza_builder;
use base qw{ pizza_builder };
sub build_dough {
 my( $self ) = @_;
 $self-&gt;{pizza}-&gt;set_dough("cross");
sub build_sauce {
 my( $self ) = @_;
 $self-&gt;{pizza}-&gt;set_sauce("mild");
sub build_topping {
 my( $self ) = @_;
 $self-&gt;{pizza}-&gt;set_topping("ham+pineapple");
1;
package spicy_pizza_builder;
use base qw{ pizza_builder };
sub build_dough {
 my( $self ) = @_;
 $self-&gt;{pizza}-&gt;set_dough("pan baked");
sub build_sauce {
 my( $self ) = @_;
 $self-&gt;{pizza}-&gt;set_sauce("hot");
sub build_topping {
 my( $self ) = @_;
 $self-&gt;{pizza}-&gt;set_topping("pepperoni+salami");
1;
package waiter;
sub new {
 return bless {
 pizza_builder =&gt; undef
 }, shift;
sub set_pizza_builder {
 my( $self, $builder ) = @_;
 $self-&gt;{pizza_builder} = $builder;
sub get_pizza {
 my( $self ) = @_;
 return $self-&gt;{pizza_builder}-&gt;get_pizza;
sub construct_pizza {
 my( $self ) = @_;
 $self-&gt;{pizza_builder}-&gt;create_new_pizza_product;
 $self-&gt;{pizza_builder}-&gt;build_dough;
 $self-&gt;{pizza_builder}-&gt;build_sauce;
 $self-&gt;{pizza_builder}-&gt;build_topping;
1;
package main
my $waiter = waiter-&gt;new;
my $hawaiian_pb = hawaiian_pizza_builder-&gt;new;
my $spicy_pb = spicy_pizza_builder-&gt;new;
$waiter-&gt;set_pizza_builder( $hawaiian_pb );
$waiter-&gt;construct_pizza;
my $pizza = $waiter-&gt;get_pizza;
print "Serving a nice pizza with:\n";
for (keys %$pizza) {
 print " $pizza-&gt;{$_} $_\n";
1;
PHP.
/** Product **/
class Pizza{
 private $dough;
 private $sauce;
 private $topping;
 public function setDough($dough){
 $this-&gt;dough = $dough;
 public function setSauce($sauce){
 $this-&gt;sauce = $sauce;
 public function setTopping($topping){
 $this-&gt;topping = $topping;
/** Abstract builder **/
abstract class PizzaBuilder{
 protected $pizza;
 public function __construct(){
 $this-&gt;pizza = new Pizza();
 public function getPizza(){
 return $this-&gt;pizza;
 abstract function buildDough();
 abstract function buildSauce();
 abstract function buildTopping();
/** Concrete builder **/
class SpicyPizza extends PizzaBuilder{
 public function buildDough(){
 $this-&gt;pizza-&gt;setDough('crispy');
 public function buildSauce(){
 $this-&gt;pizza-&gt;setSauce('hot');
 public function buildTopping(){
 $this-&gt;pizza-&gt;setTopping('pepperoni+salami');
/** Director **/
class Chef{
 private $pizza_builder;
 public function setPizzaBuilder(PizzaBuilder $pizza_builder){
 $this-&gt;pizza_builder = $pizza_builder;
 public function cookPizza(){
 $this-&gt;pizza_builder-&gt;buildDough();
 $this-&gt;pizza_builder-&gt;buildSauce();
 $this-&gt;pizza_builder-&gt;buildTopping();
 public function getPizza(){
 return $this-&gt;pizza_builder-&gt;getPizza();
//Customer orders a Pizza.
$chef = new Chef();
$order = new SpicyPizza();
$chef-&gt;setPizzaBuilder($order);
$chef-&gt;cookPizza();
$pizza = $chef-&gt;getPizza();
print_r($pizza);