The builder pattern is a creational design pattern that’s used when you need to construct complex objects that can take many optional and required parameters to create a single object. Using this pattern we can separate the construction of complex objects from their representation so that we can use the same construction process over and over to create different representations.
Examples of Complex Objects
Let's take creating a User object as an example. Now, a User can have many optional fields such as name, age, date of birth, address, email, permissions, etc… which makes it a complex object to create for different users because not every user will have all of this information associated with them.
Or another example is that you’re ordering a new custom PC. You’ll need to specify how much RAM you want, how much storage, the type of storage, what graphics card it should have, what kind of cooling system, etc… These specifications would be different for everyone that orders a new custom PC which makes this a complex object to build as well.
As stated earlier, the builder pattern will allow us to separate the construction of these objects from their representation. In the following sections, we’ll see how we can create these complex objects in a way that’s easily reusable and allows us to write clean and readable code.
Let's take a look at a couple of examples and look at the usefulness of the builder pattern. In this section, we’ll be looking at and discussing how you would approach building complex objects without the builder pattern, and then we’ll take a look at how you’d do the same with the pattern.
Without the Builder Pattern
The example above probably looks like something you’ve seen in the past. You have a simple class and you pass in parameters to the constructor to create the object. There’s nothing wrong with doing it this way but as you can see it’s pretty hard to guess what the third, fourth, and last parameters are supposed to be. Sure, you can look at the parameters that the constructor takes but in a large project you probably wouldn’t be constructing the object in the same file.
Just imagine if the User had 20 or more fields that could be set. Without using the builder pattern we’d have to pass in empty strings
undefined for all of the values that the user didn’t provide. That would get messy and confusing really fast.
This example is with just one user though. What if you needed to create a few different users, different representations of users, each with their own set of different properties. In that case, you’d need to remember all of the parameters or go back and forth to see which value corresponds to which parameter.
Lets now take a look at how the Builder Pattern helps in solving this problem.
With the Builder Pattern
The Builder Pattern allows us to create a class with methods for each property that the object would have. Taking the same User example, the Builder class would have a separate method for name, age, dob, email, etc… and each method would set the property value to the User object.
Sounds confusing? It’s actually pretty easy, lets take a look at the following example.
Now, this may seem like a lot more code upfront but I want you to look at the upside of this approach. You only need to spend a bit of time upfront to create the Builder class but later when you’re creating different
User objects you don’t need to remember all of the different parameters that the
User class takes.
this from each method, you’re able to chain the method calls together to create your complex object. You simply call the different methods on the
UserBuilder class and pass in the values the user needs.
It makes creating different representations of
User a lot easier, cleaner, and more declarative.
That’s all there is to the Builder Pattern.
In this post, you learned the benefits of using the Builder Pattern and how you can implement your own to make your code easier to read and understand. If you see your self adding way too many optional parameters to your constructor that means you’re probably creating a complex object and may need to consider a design pattern for the creation of that object.
Have any questions related to what we discussed in this post? Feel free to ask anything related to the comments.
Well, that’s all for now. Until next time, peace ✌️