Design Patterns — A quick guide to Builder pattern.

What if the client forgets and then we send a plain pizza to the customer?The solution to all these questions is the builder pattern.

We need a “builder” to construct a pizza step by step.

At the same time, the client will be safe to “order” a specific pizza and have the builder build it for him.

Step 1 — KeywordsRepresentation: An object can have different representations.

For example, a pizza can have tomato mozzarella toppings and another representation of pizza would be with mushrooms and parma ham.

Construction code: Objects can be constructed in different ways, for example using constructors.

Constructors can be overloaded, they have the same name (name of the class) but a different number/types of arguments.

Depending on the number and type of arguments passed, the specific constructor is called.

It is easy to fall into the trap of having a class of numerous constructors where each one is taking a different number of parameters.

The developer is forced to instantiate the class with the correct combination of parameters on each situation.

This problem has a name, it is a popular anti-pattern called the telescoping constructor and builder pattern is the go-to solution for it.

Let’s oversimplify Builder pattern by bluntly saying:The Builder pattern’s main intent is to have the minimum number of overloading constructors to support the constuction of several representations of an object.

Step 2 — Diagram (By example)Let’s stick to the pizza example.

In summary, we have the pizza class, the cook and the concrete builders that inherit from the abstract builder.

We will explain the diagram bottom to top:Pizza_Product: This class is the actual pizza.

It is represented by three attributes: (1) Dough, (2) sauce and (3) toppings.

ConcreteBuilder: Each concrete builder is responsible for a specific representation.

In this example, we have Margherita and Spicy Pizza.

Both concrete builders are responsible to “build” their own representation of pizza based on the three attributes listed above.

AbstractBuilder: Contains a pizza member variable and the concrete builders inherit from it.

Cook_Director: In this example, the director is the actual cook.

The class is responsible to initiate the construction of a given representation by putting the pieces together such that the builder will follow and adapt according to the director’s needs.

Step 3 — Code by exampleI would suggest to copy the code class by class from my git repository “Andreas Poyias” or the snippets below (in the order provided) and paste it in any of the available online C++ editors like c++shell, jdoodle , onlineGDBand run it to observe the output.

Then read the comments or description below.

Take time reading it thoroughly (that means one minute, not less and not more).

Product:This is the pizza class.

It is a simple class with three setters and a taste() method that prints all the ingredients.

#include <iostream>#include <memory> // unique_ptrusing namespace std;class Pizza_Product{public: void setDough(const string& dough) { m_dough = dough; } void setSauce(const string& sauce) { m_sauce = sauce; } void setTopping(const string& topping) { m_topping = topping; }void taste() const{ cout << "Pizza with " << m_dough << " dough, " << m_sauce << " sauce and " << m_topping << " topping.

Mmmmmmm.

" << endl;}private: string m_dough; string m_sauce; string m_topping;};Abstract Builder:The abstract builder is an interface that contains a pizza object.

It has a getter that returns the pizza object and a method to instantiate the pizza object.

It also declares the three builder methods that will be implemented by the concrete builders further down.

class Pizza_Builder{public: virtual ~Pizza_Builder() {}; Pizza_Product* getPizza(){ return m_pizza.

release(); } void createNewPizzaProduct() { m_pizza = make_unique<Pizza_Product>(); } virtual void buildDough() = 0; virtual void buildSauce() = 0; virtual void buildTop() = 0;protected: unique_ptr<Pizza_Product> m_pizza;};Concrete Builders:Two examples of concrete builders and two representations of a pizza.

They both implement their own build methods using the m_pizza object from the parent class (Abstract builder)class Margherita_ConcreteBuilder : public Pizza_Builder{public: virtual void buildDough() { m_pizza->setDough("cross"); } virtual void buildSauce() { m_pizza->setSauce("tomato"); } virtual void buildTop() { m_pizza->setTopping("mozzarela+basil"); }};class Spicy_ConcreteBuilder : public Pizza_Builder{public: virtual void buildDough() { m_pizza->setDough("pan baked"); } virtual void buildSauce() { m_pizza->setSauce("tomato+chilli"); } virtual void buildTop(){ m_pizza->setTopping("pepperoni+salami"); }};Director:This class puts everything together.

It has a Pizza_Builder variable.

It uses the makePizza()to receive a concrete builder as a parameter.

Then calls the build operations which work for both representations accordingly.

Therefore we achieve the purpose of having one construction-code to represent different types of pizzas.

The tastePizza()method is to print the contents of a pizza.

class Cook_Director{public: void tastePizza(){ m_pizzaBuilder->getPizza()->taste(); }void makePizza(Pizza_Builder* pb) { m_pizzaBuilder = pb; m_pizzaBuilder->createNewPizzaProduct(); m_pizzaBuilder->buildDough(); m_pizzaBuilder->buildSauce(); m_pizzaBuilder->buildTop(); }private: Pizza_Builder* m_pizzaBuilder;};Main (client): The main method operates as the client(the same as the previous guides).

It is so easy for the client to be able to build different representations of a pizza.

We need the director, and then, by just passing two different concrete builders as a parameter to themakePizza, we will be able totaste two different types of pizzas.

int main(){ Cook_Director cook; Margherita_ConcreteBuilder margheritaBuilder; Spicy_ConcreteBuilder spicyPizzaBuilder; cook.

makePizza(&margheritaBuilder); cook.

tastePizza(); cook.

makePizza(&spicyPizzaBuilder); cook.

tastePizza();}// Output// Pizza with cross dough, tomato sauce and mozzarela+basil topping.

// Mmmmmmm.

// Pizza with pan baked dough, tomato+chilli sauce and// pepperoni+salami topping.

Mmmmmmm.

Let’s summarise the benefits of this pattern:There are many possible representations but only one common input.

We have a standard protocol for creating all possible representations.

The steps of this protocol are clearly exposed by a Builder interface.

There is one derived concrete class for each target representation.

It is easy for a developer to add a new self-maintained and independent representation (of a Pizza) without the fear of breaking something else.

The client can simply register the ConcreteBuilder to the Director and get the expected representation.

The next blog will be a quick guide to the Decorator design pattern.

It is a structural pattern which is a must have to your knowledge repository.

Don’t forget to like/clap my blog-post and follow my account.

This is to give me the satisfaction that I helped some fellow developers and push me to keep on writing.

If there is a specific design pattern that you would like to learn about then let me know in the comments below so I can provide it for you in the next few weeks.

Other quick-guides on design patterns:Design Patterns — A quick guide to Abstract Factory.

Design Patterns — A quick guide to Singleton Pattern.

Design Patterns — A quick guide to Facade Pattern.

Design Patterns — A quick guide to Observer Pattern.

Design Patterns — A quick guide to Bridge Pattern.

.

. More details

Leave a Reply