Design patterns have always been a fancy term thrown around by developers. However, design patterns are not useful if they are utilized without a reason or without solving a problem.
Simply put, design patterns are a tried and tested way of solving a problem without fail. The results of following a design pattern should always be the same. This is similar to a waffle recipe that says mix “1 cup of flour and 1 cup of water”. The results of this exact measurement will be the same everywhere, at least on earth.
In my opinion, the builder design pattern is designed to eliminate the clutter of using long constructors and it helps to encapsulate the business logic of the principal class.
Let’s unpack that statement with an example. Assume we were tasked to create an Omelette class that creates an instance of an Omellete. The business requirements of this class are:
· Must be able to specify the number of Eggs to be used.
· Should have a serving of Carrots or not
· Should have a serving of Oil or not
· Should have a pinch of Salt or not
· Should have a serving of Green Peppers or not
· Specify any number of extra ingredients, let’s say the chef will like to add any number of ingredients.
Let’s create this class using POJO.
This implementation will require the use of a constructor to create an instance of the Omelette class. This can get long as new instance variables are added. Let’s create an instance.
Omelette plainOmelete = new Omelette(2, true, true, true, true);
This method is straightforward but it will also require the developers to know exactly what each variable added means. Each person will have to know what “(2, true, true, true, true)” means. Nonetheless, the biggest downside is that the constructor can grow longer and complex as more business logic increases constructor clutter and complexity increases.
Let’s use the builder method to reduce complexity. We will be utilizing method chaining for this. You can check out my short article on Method Chaining here.
The builder pattern combined with Method Chaining achieves simple intuitive instance creation while giving the benefit of thread safety that method chaining alone cannot provide.
In this case, when an instance is created it is intuitive. Let’s look at it.
Omelette breakfastOmelete = Omelette.omeletebuilder().numberOfEggs(2).hasCarrots(false).hasOil(true).hasSalt(true).hasGreenPeppers(true).addExtraIngredient("Parsley").addExtraIngredient("Ginger").fry();
This method is more intuitive because the variables needed to create an instance are labeled in plain text. Each time a new instance variable is added a new chain is made and it’s easy to notice the change. This method restricts the creation of an Omelette directly and makes sure our Omelette can only be created by a chef (Builder pattern).
To summarize the builder pattern helps with:
- Hiding the complexity of creating an instance of an object
- Thread safety when using method chaining
- Making instantiation of complex objects more readable.
If you have gotten to this point, I commend you! Thanks for reading!