Builder Design Pattern
Builder Desing Pattern is a type of creational design pattern which is used to create complex objects in a step-by-step approach. The aim of Builder Pattern is to separate the construction logic of objects away from their representation. This can help us to create different representations of the object using the same construction logic.
But why do need this?
Why do we need to encapsulate the object creation logic away from its representation? And what is the need of creating the objects in a step-by-step approach? Until now we have always created objects using the new keyword, so why suddenly do we need to create objects via a Builder? To understand these questions, let take a small example.
In the above example we see a small class called as Employee. To create its object we can use a parameterized constructor. Let’s suppose that out of name and age, the name parameter is mandatory while age is optional.
To cater this need, we need to create a parameterized constructor with name as the parameter. The optional field age can be set if required by creating a new constructor with parameter both name and age.
The above solution is extremely short sighted. What if the Employee class’s field grew from 2 fields to 20 fields out of which 10 are optional. While creating it’s object, if we choose the constructor to set the value of fields then we will have numerous constructors.
We can also create a single parameterized constructions with all the fields of the class. And the ones which are optional, we can pass some default values while the creation of the object.
createObject(“Tushar”,22,0,0,0,””);
As observed we needed to pass default values such as 0 and “” for some optional fields. To be frank , the above code is ugly. This can grow with the increase in the number of fields. It is unmaintainable as well as posses a very poor readability.
You could argue that we can create setters and then set the values with the help of those setters. But it posses some problems:
- Creating object and then populating values can result our object being in inconsistent state. That is what if the developer forgets to set the mandatory fields? This will further introduce bugs in our code.
- You could argue that we can create a parameterized constructor containing mandatory values and use setters for optional Field. That could be one of the solution to our problem. But this also comes with one huge disadvantage. We will loose immutability as we have provided setters for accessing our fields. Therefore if the idea of immutability is in picture, then we are forced to rule Setters out.
To solve these problems we use Builder Design Patterns. The crux of Builder is to construct objects ,which can be immutable very easily , providing a very readable and easy solution to create our objects. We can also provide some validation in the builder to validate the values we are trying to set to the fields.
Let’s now understand how can we implement Builder Design Pattern.
Let’s suppose that we are creating an object of the class called as PaymentInformation. This is an immutable class as payment information once processed remains the same and should not be allowed to change.
- The first thing to notice is that the constructor of our PaymentInformation class is private. This means that we cannot create the Object of the class directly(i.e using new keyword)
- All the data members are private and no setters provided to set the value in the data members. This means that essentially the class is immutable.
- We have create a static inner class called as PaymentInformationBuilder. This will act as the builder of our class PaymentInformation.
- The PaymentInformationBuilder has parameterized constructor which contains the mandatory field values as parameters.
- To set the optional field we have individual methods having name same as the field name.
- To finally build the object of PaymentInformation we have a build method. The build method calls from private constructor which initialises the object of PaymentInformation. The private constructor will be visible to PaymentInformationBuilder.
- We finally return the created object of PaymentInformation from build method.
- Once the object is created and returned, we do not have any option to edit the value of the fields.
The driver class will look something like this:
We create a new Builder Object and then use its method to set the value of various fields. As you can observe that the readability is a lot better as compared to constructors.
As observed the creation logic of a class is separated away from its representaion.
I hope you like the article. Any suggestion for the improvement is more than welcome!
The source code of the example is available in my github repository: