Introduction:
Builder is a creational design pattern that lets you construct complex object step by step. The pattern allows you to create different types and representation of an object using the same construction code.
Builder pattern suggest that extract the object construction code from its own class , and move it to separate class called builders. This pattern organize the object construction into set of steps. We no need to call all the steps. We need to invoke only the step which is required to build the object. Some of the construction steps might require different implementation when you need to build various representations of the product. For example, walls of a cabin may be built of wood, but the castle walls must be built with stone.
In this case, you can create several different builder classes that implement the same set of building steps, but in a different manner. Then you can use these builders in the construction process (i.e., an ordered set of calls to the building steps) to produce different kinds of objects.
For example, imagine a builder that builds everything from wood and glass, a second one that builds everything with stone and iron and a third one that uses gold and diamonds. By calling the same set of steps, you get a regular house from the first builder, a small castle from the second and a palace from the third. However, this would only work if the client code that calls the building steps is able to interact with builders using a common interface.
You can go further and extract a series of calls to the builder steps you use to construct a product into a separate class called director. The director class defines the order in which to execute the building steps, while the builder provides the implementation for those steps.
source: refactoring guru
Implementation:
Design a program to create Car and Manual object from the same builder interface.
Sourcecode:https://github.com/krishnaKSA/design_patterns_cplusplus/blob/main/BuilderPattern/BuilderPattern.hpp
Class diagram:
Product class:
//Product class
//Car
class Car
{
private:
uint8_t seats;
uint8_t airbag;
bool gps;
bool rearCamera;
bool sportsEngine;
uint8_t doors;
public:
Car()
{
}
void setSeats(uint8_t seats)
{
this->seats = seats;
}
void setAirbags(uint8_t airbags)
{
this->airbag = airbags;
}
void setGps(bool gps)
{
this->gps = gps;
}
void setRearCamera(bool rearCamera)
{
this->rearCamera = rearCamera;
}
void setSportsEngine(bool sportsEngine)
{
this->sportsEngine = sportsEngine;
}
void setDoors(uint8_t doors)
{
this->doors = doors;
}
};
//Car Manual
class CarManual
{
private:
uint8_t seats;
uint8_t airbag;
bool gps;
bool rearCamera;
bool sportsEngine;
uint8_t doors;
public:
CarManual(){}
void setSeats(uint8_t seats)
{
this->seats = seats;
}
void setAirbags(uint8_t airbags)
{
this->airbag = airbags;
}
void setGps(bool gps)
{
this->gps = gps;
}
void setRearCamera(bool rearCamera)
{
this->rearCamera = rearCamera;
}
void setSportsEngine(bool sportsEngine)
{
this->sportsEngine = sportsEngine;
}
void setDoors(uint8_t doors)
{
this->doors = doors;
}
uint8_t getSeats()
{
return seats;
}
};
Builder Interface class:
//BuilderInterface
class IBuilder
{
public:
virtual void reset() = 0;
virtual void buildDoors(uint8_t value) = 0;
virtual void buildAirbags(uint8_t value) = 0;
virtual void buildSeats(uint8_t value) = 0;
virtual void buildEngine(bool value) = 0;
virtual void buildGps(bool value) = 0;
virtual void buildRearCamera(bool value) = 0;
};
Concrete builder classes:
//Manual Car builder class
class ManualCarBuilder : public IBuilder
{
private:
Car* car;
public:
void reset()
{
car = new Car();
}
Car* getProduct()
{
return car;
}
void buildDoors(uint8_t value) override
{
car->setDoors(value);
}
void buildAirbags(uint8_t value) override
{
car->setAirbags(value);
}
void buildSeats(uint8_t value) override
{
car->setSeats(value);
}
void buildEngine(bool value) override
{
car->setSportsEngine(value);
}
void buildGps(bool value) override
{
car->setGps(value);
}
void buildRearCamera(bool value) override
{
car->setRearCamera(value);
}
};
//Car manual builder class
class ManualBuilder : public IBuilder
{
private:
CarManual* manual;
public:
void reset()
{
manual = new CarManual();
}
CarManual* getProduct()
{
return manual;
}
void buildDoors(uint8_t value) override
{
manual->setDoors(value);
}
void buildAirbags(uint8_t value) override
{
manual->setAirbags(value);
}
void buildSeats(uint8_t value) override
{
manual->setSeats(value);
}
void buildEngine(bool value) override
{
manual->setSportsEngine(value);
}
void buildGps(bool value) override
{
manual->setGps(value);
}
void buildRearCamera(bool value) override
{
manual->setRearCamera(value);
}
};
Director class:
//director class
class Director
{
private:
IBuilder* builder;
public:
Director()
{
builder = nullptr;
}
//set builder object
void setBuilder(IBuilder* builder)
{
this->builder = builder;
}
//Build normal car
void BuildNormalCar()
{
this->builder->reset();
this->builder->buildAirbags(2);
this->builder->buildDoors(4);
this->builder->buildSeats(4);
this->builder->buildEngine(false);
this->builder->buildGps(true);
this->builder->buildRearCamera(true);
}
//build sports car
void BuildSportsCar()
{
this->builder->reset();
this->builder->buildAirbags(2);
this->builder->buildDoors(2);
this->builder->buildSeats(2);
this->builder->buildEngine(true);
this->builder->buildGps(true);
this->builder->buildRearCamera(true);
}
};
Client code:
void testClientCode()
{
ManualCarBuilder* carBuilder = new ManualCarBuilder();
ManualBuilder* manualBuilder = new ManualBuilder();
Director* director = new Director();
//set car builder object
director->setBuilder(carBuilder);
director->BuildNormalCar();
//set manual builder object
director->setBuilder(manualBuilder);
//get sports car
director->BuildSportsCar();
//get the car manual for sports car
CarManual* manual = manualBuilder->getProduct();
}