Builder Pattern

Builder is a creational design pattern and it aims to separate the construction of a complex object from its representation so that the same construction process can create different representations. Idea here it to use same construction code (logic or process) to build different types and representation of an object.

Key to this is we extract the object construction code out of its own class and move it to separate classes called builders.

Now, let's look at why and when we need builder pattern. Imagine building a complex object which takes lots of inputs to create the final structure. A typical way is we create a class with constructor and pass on all the data to constructor as parameters. Problem is when we have too many parameters which might or might not be used in all cases. We also have to remember the order in which we always have to pass the parameters and not to forget that the code here will not look clean. Builder pattern helps in solving such problems.

Builder pattern is best suited in scenarios where building of object is step by step. At the end of the process you will have object ready.

Actual example where builder pattern can be used -

Creation of online brokerage account process:

There are types of brokerage account like cash, margin, retirement accounts

It is a step by step process of taking many inputs from user and creating account at the final step.

First it asks for personal details, contact information,

then followed by previous experince in brokerage,

trading limits,

social security details, credit history if it is margin account,

annual income,

savings etc

followed by uploading identity information and supporting income documents.

finally creating account.

Below example should help us understand practically to implement builder pattern.

Let's build pizzas. Note that pizza making process is same for all types of pizza but only ingredients (data) differ. This is where builder pattern can be used.

Let's first create a simple Pizza class with 6 properties and a method to display the values of properties.

To prepare a pizza we first have to prepare dough then roll it, add base sauce, add cheese followed by toppings. Finally bake it. This process of creating a pizza is same across and applies to (almost) all types of pizzas we are aware of.

Further to this, what type of crust, what type of toppings and cheese etc are all just data and this data is captured in above class "Pizza".

Let's first create an abstract class to include all these processing steps.

There are 6 abstract methods here mapped to each processing step. We will let child classes implement them.

For simplicity, let's say we would like to create 2 pizzas. One being Veggie pizza and other is Pepperoni. Ingredients, crust type, base sauce , cheese type and toppings differ for these pizzas.

These classes inherit from abstract class PizzaBuilderProcess. These child classes as shown below override methods to create their own specific version.

Next important step is actually putting these processing steps together in sequence. For example, we would like to add base sauce first and then add cheese not the other way.

For this, let's create a class called "PizzaMaker". Constructor of this class takes "PizzaBuilderProcess" as parameter and this is how we are coupling 2 classes together. This class is highly dependent on PizzaBuilderProcess and that's our intention.

Here we are creating PizzaMaker class which actually puts all steps together in the sequence we would like to make pizza. BuildPizza() method is responsible for this.

We want clients to invoke "BuildPizza" method.

Finally, client has to just follow and write these simple steps to get their pizza of choice.

Client creating Pacific Veggie pizza

Client creating Pepperoni pizza