Let’s understand it by understanding the assembling of computer. When you buy computer (in India), you have two choices,
For this post, we are only interested in the second option.
When you are assembling your PC, you have an option of selecting which Mother board will you use (Intel / AMD etc.), you can choose the CD/DVD drive (Samsung , Asus, Sony, LG), you can choose which Hard disk you will use (Sony, Asus, Segate etc.), you can choose which company’s (and of what size) RAM will you use, and so on..
This way we are assembling our computer. Final product is the computer which consists of small objects (RAM, Hard disk motherboard, DVD drive etc).
Similarly in Software, an object of a big class (say College) will hold objects of smaller classes (say Library, Lab, etc).. while constructing the object of the bigger class, you have to construct the objects of smaller class also. This process of building the object of a bigger class is a very good case for applying the Builder Design Pattern
The Builder Pattern simplifies the construction of complex objects by only specifying the type and content that the object requires. The construction process of the complex object will therefore allow for different representations of the complex object to be created by the different builders. Each of the concrete builder objects will construct a different representation of the complex object.
The way each Assembler may assemble a different PC but all the PC will be same products (they may have different specifications but they will all be Desktop Computers).
Participant Classes
Following are the participant classes in this pattern:
The client interacts with the Director and Builder classes.
Example:
The most rampant example for this design pattern is Pizza Builder. A normal Pizza essentially has three things
Sauce
Dough
Toppings
1. Dough: The Floor (aata) base used in the Pizza
2. Sauce: The liquid sauce on the top of base.
3. Topping: What we see on the top of it, the Onion, capsicum etc.
Let us say, There can be 2 types of Pizzas, HawaiianPizza and SpicyPizza.. Both will differ in the kind of dough, Sauce and Toppings.. but the end product will be Pizza only (If the three are properties of Pizza, then the objects will have different properties).
Now lets look at it from OOPs point of view.. there are following classes
1. Pizza – The Product class
class Pizza { private: string dough_; string sauce_; string topping_; public: void dough(const string& dough) { dough_ = dough; } void sauce(const string& sauce) { sauce_ = sauce; } void topping(const string& topping) { topping_ = topping; } void open() const { cout << "Pizza with " << dough_ << " dough, " << sauce_ << " sauce and " << topping_ << " topping. Mmm." << endl; } };
2. PizzaBuilder – The Builder class (Abstract)
class PizzaBuilder { protected: Pizza pizza_; // Concrete Classes will use it hence 'Protected' public: const Pizza& pizza() { return pizza_; } // Pure virtual functions virtual void buildDough() = 0; virtual void buildSauce() = 0; virtual void buildTopping() = 0; };
3. HawaiianPizzaBuilder / SpicyPizzaBuilder – The Concrete Builder class, to build the two types of Pizzas
/** Build the Hawaiian Pizza (the Dough, Sauce & Toppings according to this pizza) */ class HawaiianPizzaBuilder : public PizzaBuilder { public: void buildDough() { pizza_.dough("cross"); } void buildSauce() { pizza_.sauce("mild"); } void buildTopping() { pizza_.topping("ham+pineapple"); } }; /** Build the SpicyPizza (the Dough, Sauce & Toppings according to this pizza) */ class SpicyPizzaBuilder : public PizzaBuilder { public: void buildDough() { pizza_.dough("pan baked"); } void buildSauce() { pizza_.sauce("hot"); } void buildTopping() { pizza_.topping("pepperoni+salami"); } };
4. Cook – The director class
//---------------------------------------------------------------- class Cook { private: PizzaBuilder* pb; public: // default constructor Cook():pb(NULL){ ; } // Destructor ~Cook() { if (pb) delete pb; } void pizzaBuilder(PizzaBuilder* pizzaBuilder) { if (pb) delete pb; pb = pizzaBuilder; } const Pizza& getPizza() { return pb-<pizza(); } // Building the Pizza. This knows the sequence in which to build individual items void constructPizza() { pb-<buildDough(); pb-<buildSauce(); pb-<buildTopping(); } };
Using the Pizza Builder. Below code has the main function which use the above code:
int main() { Cook cook; cook.pizzaBuilder(new HawaiianPizzaBuilder); cook.constructPizza(); Pizza hawaiian = cook.getPizza(); hawaiian.open(); cook.pizzaBuilder(new SpicyPizzaBuilder); cook.constructPizza(); Pizza spicy = cook.getPizza(); spicy.open(); }
2 Comments
Good and simple example.
thanks rakesh