A Mysterious yet powerful variation of a well-known design pattern
The Force is strong with this one pattern
If you are a software engineer working on developing web applications, microservices, or any piece of software then there is a good chance you may have come across the Builder design pattern. In this article, we are going to learn a popular version of the Builder pattern known as the Faceted Builder.
Note: This article assumes you already know how the Builder pattern works. If you don’t, please make sure you read my article on Builder pattern here before you proceed further.
Just before we begin if you might be wondering what the pattern looks like, it looks as follows.
As we can see, the Person object has been built in multiple steps that includes building of name, age, address, employment information. As you may have guessed already the Person class has been coded to use multiple builders for few fields that are a bit complex (having too many fields) to be built with a single builder. The advantage of this is we have separate builders that are concerned with the building of their own specific thing about a Person. For example, Name builder is concerned with building(creating/setting) the first & last name of the Person object and similarly Address builder is only concerned with building(creating/setting) information related to Street address, state, zipcode, etc.
Let's now see how the above code was implemented. Let’s consider the same person class with the following fields to store necessary information.
To create a person object we now create the PersonBuilder class as follows,
We initialize a Person object and create a method to set the age of the person(This builder is only responsible to build age field at the moment). Since our goal is to create a builder we return back the same class (PersonBuilder). And in order to convert the PersonBuilder to Person we create a build method to return back the actual Person object. Now comes the fun part, in order to create/build the other fields we create separate builder classes. For example, let us take the Employment information builder.
The reason we extend the PersonBuilder class is to be able to jump back and forth from PersonBuilder class to PersonEmploymentBuilder class. The reason we create the constructor with the Person argument is to connect the PersonBuilder class and PersonEmploymentBuilder class, if you think about it when performing the operations on PersonBuilder and to switch to PersonEmploymentBuilder we need to continue working on the same person object, so we send the person object to the PersonEmploymentBuilder and since we are extending the PersonBuilder class we already have the person field by inheritence. Now, similar to the aged method we created earlier we create the employedBy() & getsPaid() methods to build(set) the employer & salary fields respectively. Now, there is one thing left here, that is to be able to reach the PersonEmploymentBuilder from the PersonBuilder class. That can be done by adding this method.
Similarly, we create PersonAddressBuilder, PersonNameBuilder classes as follows.
And we connect to these classes from the PersonBuilder as follows.
One thing which we didn't focus in detail earlier was the reason why its extremely important to extend the PersonBuilder. By using inheritance we are making sure we can switch between different subclass builders using the named(), address(), employmentDetails() methods available in PersonBuilder class that get inherited to all the subclasses.
Finally, we add some helper methods in the Person class to make our lives easy.
So, this is how we can achieve the Faceted builder pattern which enables us to generate fluent APIs using multiple builders. You can find the entire source code for this article here. If you like this article please don't forget to clap as that would motivate me to write more articles like this. Also, if you are interested in staying in touch for more articles, make sure to follow me & also check out my articles as well. With that being said I thank you for reading it this far and see you in the next one! :)