Wednesday, April 2, 2014

Builder Design Pattern Implementation in C++


Sometimes an application gets too complicated and developing it becomes a pain. These applications contain complex objects which are made up from other objects from different classes. Now these objects may vary. So there has to be a process of building the complex objects so that there is scope of building different products using the same process.

That is when a creational design pattern called Builder comes into picture. It separates the details of construction process from its representation

Now what in the world that line means actually ? 

It means that the construction process is made so generic, that multiple products can be produced using the same process. e.g. construction workers. Different type of buildings can be built using the same workers and same common set of process.

Here is a class diagram of the design pattern.

Builder Design Pattern
Builder Design Pattern
There are 4 major components:

  1. Director: It constructs an object using the Builder interface.
  2. Builder : It specifies an abstract interface to build parts of a product.
  3. Concrete Classes : Implements builder interface.
  4. Product : The complex object which is created at the end. 

Director object is created and Builder interface is used. It notifies the Builder to create each part of the product. Upon the request from Director, Builder adds parts to the product. Finally the product is returned by the Builder.

We have to take care of when to use the Builder Design Pattern. Few points come into mind :
  • When the object to be created is complex enough and can have multiple representations.
  • When the construction process can be broken down into multiple steps
  • When the process of creation of an object can be independent of the parts to be used.
  • When different products can have a common abstract class.
Now lets create a builder design pattern using an example.

Builder Design Pattern
Builder Example

In this example we create house as product. Now the house created may be different as per requirement of different people. It can be a lavish house with lots of amenities and expensive stuff. On the other hand, it could be a normal house with normal stuff.

  • The HouseBuilder class is the builder class which provides interface for creating the parts of the house.
  • The House class is the final product that we want to build
  • LavishHouse and NormalHouse are the concrete classes which implement the HouseBuilder interface.
  • Contractor is the director which constructs the house using the HouseBuilder interface.


Builder Design Pattern Implementation(C++)

 #include <iostream>

using namespace std;

/* Interface that will be returned as the product from builder */
class HousePlan{
public:
 virtual void setWindow(string window)=0;
 virtual void setDoor(string door)=0;
 virtual void setBathroom(string bathroom)=0;
 virtual void setKitchen(string kitchen)=0;
 virtual void setFloor(string floor)=0;
};

/* Concrete class for the HousePlan interface */
class House:public HousePlan{
private :
 string window, door, kitchen, bathroom, floor;

public:
 void setWindow(string window)
 {
  this->window = window;
 }

 void setDoor(string door)
 {
  this->door = door;
 }

 void setBathroom(string bathroom)
 {
  this->bathroom = bathroom;
 }

 void setKitchen(string kitchen)
 {
  this->kitchen = kitchen;
 }

 void setFloor(string floor)
 {
  this->floor = floor;
 }
};

/* Builder Class */
class HouseBuilder
{
public:
 /* Abstract functions to build parts */
 virtual void buildWindow()=0;
 virtual void buildDoor()=0;
 virtual void buildKitchen()=0;
 virtual void buildBathroom()=0;
 virtual void buildFloor()=0;
 /* The product is returned by this function */
 virtual House* getHouse()=0;
};

/* Concrete class for the builder interface */
class LavishHouse:public HouseBuilder{
private:
 House *house;
public:
 LavishHouse()
 {
  house = new House();
 }

 void buildWindow()
 {
  house->setWindow("French Window");
 }

 void buildDoor()
 {
  house->setDoor("Wooden Door");
 }

 void buildBathroom()
 {
  house->setBathroom("Modern Bathroom");
 }

 void buildKitchen()
 {
  house->setKitchen("Modular Kitchen");
 }

 void buildFloor()
 {
  house->setFloor("Wooden Floor");
 }

 House* getHouse()
 {
  return this->house;
 }
};

/* Another Concrete class for the builder interface */
class NormalHouse:public HouseBuilder{
private:
 House *house;
public:
 NormalHouse()
 {
  house = new House();
 }

 void buildWindow()
 {
  house->setWindow("Normal Window");
 }

 void buildDoor()
 {
  house->setDoor("Metal Door");
 }

 void buildBathroom()
 {
  house->setBathroom("Regular Bathroom");
 }

 void buildKitchen()
 {
  house->setKitchen("Regular Kitchen");
 }

 void buildFloor()
 {
  house->setFloor("Mosaic Floor");
 }

 House* getHouse()
 {
  return this->house;
 }
};

/* The Director. Constructs the house */
class Contractor
{
private:
 HouseBuilder *houseBuilder;

public:
 Contractor(HouseBuilder *houseBuilder)
 {
  this->houseBuilder = houseBuilder;
 }

 House *getHouse()
 {
  return houseBuilder->getHouse();
 }

 void buildHouse()
 {
  houseBuilder->buildWindow();
  houseBuilder->buildDoor();
  houseBuilder->buildBathroom();
  houseBuilder->buildKitchen();
  houseBuilder->buildFloor();
 }
};

/* Example on how to use the Builder design pattern */
int main()
{
 HouseBuilder *lavishHouseBldr = new LavishHouse();
 HouseBuilder *normalHouseBldr = new NormalHouse();

 Contractor *ctr1 = new Contractor(lavishHouseBldr);
 Contractor *ctr2 = new Contractor(normalHouseBldr);

 ctr1->buildHouse();
 House *house1 = ctr1->getHouse();
 cout<<"Constructed: "<<house1;

 ctr2->buildHouse();
 House *house2 = ctr2->getHouse();
 cout<<"Constructed: "<<house2;
}