Builder Design Pattern
Overview
Builder design pattern is a creational design pattern that allows us to construct an object step-by-step. It uses a builder class that contains the construction steps to create an object.
When Will We Need Builder Design Pattern?
Imagine that we want to build software that accepts customers' details and stores them in a database. Customers are shown a form that accepts the below mandatory and optional fields.
- Mandatory Fields - First Name, Last Name, Primary Email, and Primary Mobile Number
- Optional Fields - Middle Name, Secondary Email, and Secondary Mobile Number
Ideally, we create a Customer class with the mandatory and optional attributes listed above. We create a constructor that accepts the above attributes. Since some attributes are optional, we may need to pass null values to those attributes we don't want to use. The builder design pattern lets us create an object step by step without passing all the values to the constructor.
Builder design pattern eliminates the telescopic constructor problem where we create several overloaded constructors with fewer arguments.
Example Consider creating a Customer object with mandatory attributes firstName, lastName and optional attributes middleName and age. We create several overloaded constructors that call the default constructor with default values for missing inputs.
How Does Builder Design Pattern Work?
We will understand the working of the builder design pattern with the example mentioned above. We will create a CustomerBuilder and use it to construct the customer object with the mandatory and optional parameters. Finally, we call the builder's build() method to get the constructed Customer object.
Structure
Builder design pattern consists of components such as builder interface, concrete builders, product, and client.
Builder
Builder is an interface that declares the methods used to construct the object. For example, the ICustomerBuilder interface declares methods to construct customer attributes.
Concrete Builders Concrete builders implement the builder interface and add details to the interface's construction steps. For example, CusomterBuilder adds the details to the ICustomerBuilder interface's methods.
Product
Product is a class that will be constructed through concrete builders. For example, the Customer object will be constructed via the CustomerBuilder.
Client The client is the application class that creates product objects using concrete builders.
Implementation
- Create the ICustomerBuilder interface with the construction methods such as firstName(), lastName(), middleName(), etc.
- Create the concrete builder CustomerBuilder that implements the ICustomerBuilder interface and overrides its methods. It has a build() method that returns the final Customer object.
- Create the Customer class with mandatory and optional attributes. This Customer object will be constructed through the CustomerBuilder.
- Create the Client class responsible for instantiating the CustomerBuilder and use it to build the Customer object.
Pseudocode
We implement builder design patterns by creating the Customer, CustomerBuilder, and Product classes.
Customer
Let's start by creating the Customer class with the attributes firstName, lastName, middleName, primaryEmail, primaryMobileNumber, secondaryEmail, and secondaryMobileNumber. We add only getter methods to the Customer class, making it immutable.
Pseudocode
Customer Builder
We create the customer builder interface ICustomerBuilder that declares the construction steps for the Customer object. Every construction method should return the ICustomerBuilder interface that makes the method calls chainable.
Pseudocode
Concrete Customer Builder
We create the concrete customer builder CustomerBuilder that implements the ICustomerBuilder interface and overrides all its construction methods. We add the build() that returns the final Customer object on calling.
Pseudocode
Client
We create the Client class responsible for creating the Customer objects through the CustomerBuilder.
Pseudocode
Output
Explanation
We created a CustomerBuilder instance in the main() method and constructed the object with the values firstName, lastName, primaryEmail, and primaryMobileNumber. Since we didn't pass the values middleName, secondaryEmail, and secondaryMobileNumber, they are set to null.
Language Specific Code
Java
Customer
Customer Builder
Concrete Customer Builder
Client
Output
C++
Customer
Customer Builder
Concrete Customer Builder
Client
Output
Python
Customer
Customer Builder
Concrete Customer Builder
Client
Output
Pros and Cons of Builder Design Pattern
Pros
- Builder design pattern allows us to create objects only with the required values and eliminates passing null for missing values.
- Builder design pattern eliminates the telescopic constructors (i.e.) creating overloaded constructors with various combinations of attributes.
- Builder design pattern allows us to create immutable objects. The object's attributes cannot be modified once built.
Cons
- Builder design pattern introduces additional builder code for every class and increases maintenance overhead.
Difference between Builder Design Pattern and Factory Design Pattern
Builder Pattern | Factory Pattern |
---|---|
Builder design pattern is used to construct an object step-by-step by passing the necessary values | Factory design pattern is used to build various subtypes of an object based on the requirement |
Example: PizzaBuilder constructs Pizza object with ingredients such as crust, sauce, toppings, etc. | Example: PizzaFactory creates pizzas such as PepperoniPizza, MushroomPizza, etc. |
Harness the power of Instagram System Design with our course, guiding you toward a future brimming with design possibilities.
FAQs
Q. Why do we need a Builder interface?
A. The Builder interface declares the construction steps of an object, and it can be implemented to provide various concrete builder implementations. In the below example, the PizzaBuilder interface is implemented to provide a builder for pizza dish (food) and pizza recipe (instruction).
Q. Where is the Builder design pattern used in Java?
A. In Java, the builder design pattern is used in the StringBuilder class. StringBuilder contains the append() method to construct string step-by-step, and finally, we call the toString() method to get the constructed string object.
Q. What type is the Builder design pattern?
A. Builder design pattern is a type of creational design pattern. Creational design patterns provide various mechanisms to construct and create objects.