빌더 패턴이란 복합 객체의 생성 과정과 표현 방법을 분리하여 동일한 생성 절차에서 서로 다른 표현 결과를 만들 수 있게 하는 패턴이다. 2 단어 요약 : 생성자 오버로딩
구조
예
자바
/** "Product" */classPizza{privateStringdough="";privateStringsauce="";privateStringtopping="";publicvoidsetDough(Stringdough){this.dough=dough;}publicvoidsetSauce(Stringsauce){this.sauce=sauce;}publicvoidsetTopping(Stringtopping){this.topping=topping;}}/** "Abstract Builder" */abstractclassPizzaBuilder{protectedPizzapizza;publicPizzagetPizza(){returnpizza;}publicvoidcreateNewPizzaProduct(){pizza=newPizza();}publicabstractvoidbuildDough();publicabstractvoidbuildSauce();publicabstractvoidbuildTopping();}/** "ConcreteBuilder" */classHawaiianPizzaBuilderextendsPizzaBuilder{publicvoidbuildDough(){pizza.setDough("cross");}publicvoidbuildSauce(){pizza.setSauce("mild");}publicvoidbuildTopping(){pizza.setTopping("ham+pineapple");}}/** "ConcreteBuilder" */classSpicyPizzaBuilderextendsPizzaBuilder{publicvoidbuildDough(){pizza.setDough("pan baked");}publicvoidbuildSauce(){pizza.setSauce("hot");}publicvoidbuildTopping(){pizza.setTopping("pepperoni+salami");}}/** "Director" */classCook{privatePizzaBuilderpizzaBuilder;publicvoidsetPizzaBuilder(PizzaBuilderpizzaBuilder){this.pizzaBuilder=pizzaBuilder;}publicPizzagetPizza(){returnpizzaBuilder.getPizza();}publicvoidconstructPizza(){pizzaBuilder.createNewPizzaProduct();pizzaBuilder.buildDough();pizzaBuilder.buildSauce();pizzaBuilder.buildTopping();}}/** A given type of pizza being constructed. */publicclassBuilderExample{publicstaticvoidmain(String[]args){Cookcook=newCook();PizzaBuilderhawaiianPizzaBuilder=newHawaiianPizzaBuilder();PizzaBuilderspicyPizzaBuilder=newSpicyPizzaBuilder();cook.setPizzaBuilder(hawaiianPizzaBuilder);cook.constructPizza();Pizzapizza=cook.getPizza();}}
C#
//Implementation in C#.classPizza{stringdough;stringsauce;stringtopping;publicPizza(){}publicvoidSetDough(stringd){dough=d;}publicvoidSetSauce(strings){sauce=s;}publicvoidSetTopping(stringt){topping=t;}}//Abstract BuilderabstractclassPizzaBuilder{protectedPizzapizza;publicPizzaBuilder(){}publicPizzaGetPizza(){returnpizza;}publicvoidCreateNewPizza(){pizza=newPizza();}publicabstractvoidBuildDough();publicabstractvoidBuildSauce();publicabstractvoidBuildTopping();}//Concrete BuilderclassHawaiianPizzaBuilder:PizzaBuilder{publicoverridevoidBuildDough(){pizza.SetDough("cross");}publicoverridevoidBuildSauce(){pizza.SetSauce("mild");}publicoverridevoidBuildTopping(){pizza.SetTopping("ham+pineapple");}}//Concrete BuilderclassSpicyPizzaBuilder:PizzaBuilder{publicoverridevoidBuildDough(){pizza.SetDough("pan baked");}publicoverridevoidBuildSauce(){pizza.SetSauce("hot");}publicoverridevoidBuildTopping(){pizza.SetTopping("pepparoni+salami");}}/** "Director" */classWaiter{privatePizzaBuilderpizzaBuilder;publicvoidSetPizzaBuilder(PizzaBuilderpb){pizzaBuilder=pb;}publicPizzaGetPizza(){returnpizzaBuilder.GetPizza();}publicvoidConstructPizza(){pizzaBuilder.CreateNewPizza();pizzaBuilder.BuildDough();pizzaBuilder.BuildSauce();pizzaBuilder.BuildTopping();}}/** A customer ordering a pizza. */classBuilderExample{publicstaticvoidMain(string[]args){Waiterwaiter=newWaiter();PizzaBuilderhawaiianPizzaBuilder=newHawaiianPizzaBuilder();PizzaBuilderspicyPizzaBuilder=newSpicyPizzaBuilder();waiter.SetPizzaBuilder(hawaiianPizzaBuilder);waiter.ConstructPizza();Pizzapizza=waiter.GetPizza();}}
C++
// Implementation in C++.#include<iostream>#include<memory>#include<string>// ProductclassPizza{private:std::stringdough;std::stringsauce;std::stringtopping;public:Pizza(){}~Pizza(){}voidSetDough(conststd::string&d){dough=d;};voidSetSauce(conststd::string&s){sauce=s;};voidSetTopping(conststd::string&t){topping=t;}voidShowPizza(){std::cout<<" Yummy !!!"<<std::endl<<"Pizza with Dough as "<<dough<<", Sauce as "<<sauce<<" and Topping as "<<topping<<" !!! "<<std::endl;}};// Abstract BuilderclassPizzaBuilder{protected:std::auto_ptr<Pizza>pizza;public:PizzaBuilder(){}virtual~PizzaBuilder(){}std::auto_ptr<Pizza>GetPizza(){returnpizza;}voidcreateNewPizzaProduct(){pizza.reset(newPizza);}virtualvoidbuildDough()=0;virtualvoidbuildSauce()=0;virtualvoidbuildTopping()=0;};// ConcreteBuilderclassHawaiianPizzaBuilder:publicPizzaBuilder{public:HawaiianPizzaBuilder():PizzaBuilder(){}~HawaiianPizzaBuilder(){}voidbuildDough(){pizza->SetDough("cross");}voidbuildSauce(){pizza->SetSauce("mild");}voidbuildTopping(){pizza->SetTopping("ham and pineapple");}};// ConcreteBuilderclassSpicyPizzaBuilder:publicPizzaBuilder{public:SpicyPizzaBuilder():PizzaBuilder(){}~SpicyPizzaBuilder(){}voidbuildDough(){pizza->SetDough("pan baked");}voidbuildSauce(){pizza->SetSauce("hot");}voidbuildTopping(){pizza->SetTopping("pepperoni and salami");}};// DirectorclassWaiter{private:PizzaBuilder*pizzaBuilder;public:Waiter():pizzaBuilder(NULL){}~Waiter(){}voidSetPizzaBuilder(PizzaBuilder*b){pizzaBuilder=b;}std::auto_ptr<Pizza>GetPizza(){returnpizzaBuilder->GetPizza();}voidConstructPizza(){pizzaBuilder->createNewPizzaProduct();pizzaBuilder->buildDough();pizzaBuilder->buildSauce();pizzaBuilder->buildTopping();}};// A customer ordering a pizza.intmain(){Waiterwaiter;HawaiianPizzaBuilderhawaiianPizzaBuilder;waiter.SetPizzaBuilder(&hawaiianPizzaBuilder);waiter.ConstructPizza();std::auto_ptr<Pizza>pizza=waiter.GetPizza();pizza->ShowPizza();SpicyPizzaBuilderspicyPizzaBuilder;waiter.SetPizzaBuilder(&spicyPizzaBuilder);waiter.ConstructPizza();pizza=waiter.GetPizza();pizza->ShowPizza();returnEXIT_SUCCESS;}
## Productpackagepizza;subnew{returnbless{dough=>undef,sauce=>undef,topping=>undef},shift;}subset_dough{my($self,$dough)=@_;$self->{dough}=$dough;}subset_sauce{my($self,$sauce)=@_;$self->{sauce}=$sauce;}subset_topping{my($self,$topping)=@_;$self->{topping}=$topping;}1;## Abstract builderpackagepizza_builder;subnew{returnbless{pizza=>undef},shift;}subget_pizza{my($self)=@_;return$self->{pizza};}subcreate_new_pizza_product{my($self)=@_;$self->{pizza}=pizza->new;}# This is what an abstract method could look like in perl...subbuild_dough{croak("This method must be overridden.");}subbuild_sauce{croak("This method must be overridden.");}subbuild_topping{croak("This method must be overridden.");}1;## Concrete builderpackagehawaiian_pizza_builder;usebaseqw{ pizza_builder };subbuild_dough{my($self)=@_;$self->{pizza}->set_dough("cross");}subbuild_sauce{my($self)=@_;$self->{pizza}->set_sauce("mild");}subbuild_topping{my($self)=@_;$self->{pizza}->set_topping("ham+pineapple");}1;## Concrete builderpackagespicy_pizza_builder;usebaseqw{ pizza_builder };subbuild_dough{my($self)=@_;$self->{pizza}->set_dough("pan baked");}subbuild_sauce{my($self)=@_;$self->{pizza}->set_sauce("hot");}subbuild_topping{my($self)=@_;$self->{pizza}->set_topping("pepperoni+salami");}1;## Directorpackagewaiter;subnew{returnbless{pizza_builder=>undef},shift;}subset_pizza_builder{my($self,$builder)=@_;$self->{pizza_builder}=$builder;}subget_pizza{my($self)=@_;return$self->{pizza_builder}->get_pizza;}subconstruct_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)packagemainmy$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 **/classPizza{private$dough;private$sauce;private$topping;publicfunctionsetDough($dough){$this->dough=$dough;}publicfunctionsetSauce($sauce){$this->sauce=$sauce;}publicfunctionsetTopping($topping){$this->topping=$topping;}}/** Abstract builder **/abstractclassPizzaBuilder{protected$pizza;publicfunction__construct(){$this->pizza=newPizza();}publicfunctiongetPizza(){return$this->pizza;}abstractfunctionbuildDough();abstractfunctionbuildSauce();abstractfunctionbuildTopping();}/** Concrete builder **/classSpicyPizzaextendsPizzaBuilder{publicfunctionbuildDough(){$this->pizza->setDough('crispy');}publicfunctionbuildSauce(){$this->pizza->setSauce('hot');}publicfunctionbuildTopping(){$this->pizza->setTopping('pepperoni+salami');}}/** Director **/classChef{private$pizza_builder;publicfunctionsetPizzaBuilder(PizzaBuilder$pizza_builder){$this->pizza_builder=$pizza_builder;}publicfunctioncookPizza(){$this->pizza_builder->buildDough();$this->pizza_builder->buildSauce();$this->pizza_builder->buildTopping();}publicfunctiongetPizza(){return$this->pizza_builder->getPizza();}}//Customer orders a Pizza.$chef=newChef();$order=newSpicyPizza();$chef->setPizzaBuilder($order);$chef->cookPizza();$pizza=$chef->getPizza();print_r($pizza);