Builder pattern

From Wikipedia, the free encyclopedia

The Builder Pattern is a software design pattern. The intention is to separate the construction of a complex object from its representation so that the same construction process can create different representations.

Often, Builder Pattern builds Composite pattern, a structure pattern.

Contents

[edit] Class Diagram

Builder Structure


[edit] Builder

Abstract interface for creating products.

[edit] Concrete Builder

Provide implementation for Builder. Construct and assemble parts to build the products.

[edit] Director

The Director class is responsible for managing the correct sequence of object creation. It receives a Concrete Builder as a parameter and executes the necessary operations on it.

[edit] Product

The complex object under construction.


[edit] Examples

[edit] 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 Waiter {
  private PizzaBuilder pizzaBuilder;

  public void setPizzaBuilder (PizzaBuilder pb) { pizzaBuilder = pb; }
  public Pizza getPizza() { return pizzaBuilder.getPizza(); }

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

/** A customer ordering a pizza. */
class BuilderExample {
  public static void main(String[] args) {
    Waiter waiter = new Waiter();
    PizzaBuilder hawaiian_pizzabuilder = new HawaiianPizzaBuilder();
    PizzaBuilder spicy_pizzabuilder = new SpicyPizzaBuilder();

    waiter.setPizzaBuilder ( hawaiian_pizzabuilder );
    waiter.constructPizza();

    Pizza pizza = waiter.getPizza();
  }
}


[edit] C++

 /** Implementation in C++ */
 #include  <iostream> 
 using namespace std;
 
 /** Product */ 
 class Pizza 
 {  
   string m_oStrDough;
   string m_oStrSauce;
   string m_oStrTopping;
  
   public:
   Pizza(string& _oStrDough, string& _oStrSauce, string& _oStrTopping )
     : m_oStrDough(_oStrDough), m_oStrSauce(_oStrSauce), m_oStrTopping(_oStrTopping)
     {}
 
   Pizza() {}
 
   ~Pizza() {}
 
   void SetDough(string& _oStrDough)
   {
     m_oStrDough = _oStrDough;
   }
 
   void SetSauce(string& _oStrSauce)
   {
     m_oStrSauce = _oStrSauce;
   }
 
   void SetTopping(string& _oStrTopping)
   {
     m_oStrTopping = _oStrTopping;
   }
   void ShowPizza()
   {
     cout << " Yummy !!!" << endl
       << "Pizza with Dough as " << m_oStrDough
       << ", Sauce as " << m_oStrSauce
       << " and Topping as " << m_oStrTopping
       << " !!! " << endl; 
   }
 };
 
 /** "Abstract Builder" */
 class PizzaBuilder 
 {
 
   protected:
   Pizza* m_poPizza;
  
   public:
  
   PizzaBuilder()
     : m_poPizza(NULL) {}
 
   ~PizzaBuilder() {}
 
 
   Pizza * GetPizza()
   {
     return m_poPizza;
   }
 
   void createNewPizzaProduct()
   {
     m_poPizza = new Pizza();
   }
  
   virtual void buildDough()=0;
 
   virtual void buildSauce()=0;
 
   virtual void buildTopping()=0;
 
 };
 
 /** "ConcreteBuilder" */
 class HawaiianPizzaBuilder : public PizzaBuilder 
 {
 
   void buildDough()
   {
     string oStrDought("cross");
     m_poPizza->SetDough(oStrDought);
   }
 
   void buildSauce()
   {
     string oStrSauce("miid");
     m_poPizza->SetSauce(oStrSauce);
   }
  
   void buildTopping()
   {
     string oStrTopping("ham and pineapple");
     m_poPizza->SetTopping(oStrTopping);
   }
 };
 
 /** "ConcreteBuilder" */ 
 class SpicyPizzaBuilder : public PizzaBuilder 
 {
 
   void buildDough()
   {
     string oStrDought("pan baked");
     m_poPizza->SetDough(oStrDought);
   }
  
   void buildSauce()
   {
     string oStrSauce("hot");
     m_poPizza->SetSauce(oStrSauce);
   }
  
   void buildTopping()
   {
     string oStrTopping("pepperoni and salami");
     m_poPizza->SetTopping(oStrTopping);
   }
 
 };
 
 /** "Director" */
 class Waiter 
 {
 
   PizzaBuilder* m_poPizzaBuilder;
 
   public:
 
   Waiter() : m_poPizzaBuilder(NULL) {}
   ~Waiter()
   {
     m_poPizzaBuilder = NULL;
   }
 
   void SetPizzaBuilder(PizzaBuilder* _poPizzaBuilder)
   {
     m_poPizzaBuilder = _poPizzaBuilder;
   }
  
   Pizza * GetPizza()
   {
     return m_poPizzaBuilder->GetPizza();
   }
 
   void ConstructPizza()
   {
     m_poPizzaBuilder->createNewPizzaProduct();
     m_poPizzaBuilder->buildDough();
     m_poPizzaBuilder->buildSauce();
     m_poPizzaBuilder->buildTopping();
   }
 };
 
 /** A customer ordering a pizza. */
 int main()
 { 
 
   Waiter* poWaiter = new Waiter();
 
   PizzaBuilder* poHawaiianPizzaBuilder = new HawaiianPizzaBuilder();
 
   poWaiter->SetPizzaBuilder (poHawaiianPizzaBuilder);
   poWaiter->ConstructPizza();
   Pizza* poPizza = poWaiter->GetPizza();
   poPizza->ShowPizza();
  
   PizzaBuilder* poSpicyPizzaBuilder = new SpicyPizzaBuilder();
 
   poWaiter->SetPizzaBuilder (poSpicyPizzaBuilder);
   poWaiter->ConstructPizza();
   poPizza = poWaiter->GetPizza();
   poPizza->ShowPizza();
 
   delete poWaiter;
   delete poHawaiianPizzaBuilder;
   delete poSpicyPizzaBuilder;
   return 0;
 }
 Mital d vora 11:17, 20 March 2007 (UTC).

[edit] Visual Prolog

Product

interface pizza 
   predicates 
      setDough : (string Dough). 
      setSauce : (string Sause). 
      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().

[edit] Difference Between Builder pattern and Abstract factory pattern

The Abstract factory pattern defers the choice of what concrete type of object to make until run time. E.g. going to a restaurant to order the special of the day. The waiter is the interface to the factory that takes the abstractor generic message "Get me the special of the day!" and returns the concrete product (i.e. Hawaiian or Spicy pizza)

The Builder pattern encapsulates the logic of how to put together a complex object so that the client just requests a configuration and the builder directs the logic of building it. E.g The main contractor (builder) in building a house knows, given a floor plan, how to execute the sequence of operations (i.e. by delegating to subcontractors) needed to build the complex object. If that logic was not encapsulated in a builder, then the buyers would have to organize the subcontracting themselves ("Dear, shouldn't we have asked for the foundation to be laid before the roofers showed up?")

The Abstract factory pattern is concerned with what is made, the builder with how it is made. Design patterns points out that Abstract factory is similar to builder in that it too may construct complex objects. The primary difference is that the Builder pattern focuses on constructing a complex object step by step. Abstract factory's emphasis is on families of product objects (either simple or complex). Builder returns the product as the final step, but as far as the Abstract Factory is concerned, the product gets returned immediately.

[edit] External links