Provide a flexible solution to various object creation problems
Master series of this pattern is: Here
The intent of the Builder design pattern is to separate the construction of a complex object from its representation. This Pattern provides a series of methods that provides transparency to the consumer of class to better understand what is happening under the hood.
The builder pattern keeps the logic and default configuration values required to create an object into a builder class. This allows consumer to create objects with minimal configuration data and without needing to know the default values that will be used to create the object.
What are the benefits?
- This pattern makes it easier to change the default configuration values used to create an object and to change the class from which instances are created.
When should you use this pattern?
- Use this pattern when a complex configuration process is required to create an object and you don’t want the default configuration values to be disseminated throughout the application.
- This pattern is useful when you have lots of optional parameters
- When you have to modify values later at any point of time
When should you avoid this pattern?
- Don’t use this pattern when every data value required to create an object will be different for each instance.
Pattern correct implementation check:
Consumer can create objects by providing just the data values for which there are no default values
Any related patterns:
This pattern can be combined with the factory method or abstract factory patterns
The builder pattern solves the problem by introducing an intermediary called the builder between a component and the object it needs to work with.
In the first operation, the consumer provides the builder with an item of data that replaces one of the default values [if present] used to create an object. The operation is repeated each time the consumer obtains a new value from the process it is following.
In the second operation, the consumer asks the builder to create an object. This signals to the builder that there will be no new data and that an object should be created using the data values it has received so far, along with default values for the data items that were not specified by the consumer.
In the third operation, the builder creates an object and returns it to the consumer with an object.
It might look complicated but it’s simple. We can compare it to LEGO, To build a square, we need four elements of same size. We can’t say to build until these 4 elements are provided.
To understand Builder Pattern better, I tried out many approaches, You can adopt anyone which looks better to you.
I have a class with a lot of optional values. While creating instance of particular type, it just require few values. In swift it could be easily achieved with enum with associated values, but sometimes it complicate things and a lot of duplication if there is common field present.
As I have lot of optionals in this class which is not required by all options. I just set required field values using builder. This one is first iteration but frankly I didn’t like the approach. As I need to create class to create model.
In this I have created model using struct and builder using class so there is no mutability further on struct.
Builder pattern is also useful when you have complex logic for object creation.
You would have noticed in builder pattern, each
set(#) function returns Builder itself which is duplicated line of code in each function. I was recently reading about Kotlin
also function which looks good candidate for functional programming. It’s difficult to create kotlin
apply function in swift as it’s not supported by language.
also is possible which I implemented having name
also doesn’t make sense here.
Other examples of builder pattern are PizzaBuilder, BurgerBuilder, URLComponents and DateComponents.
Block based builders
A more swifty approach can be the use of blocks instead of builder classes to configure objects.
Ofcourse, you can create generic implementation of this build function if you are really incorporating to use it for all ui views and subclasses.
Here goes UIView builder for generic implementation:
Please note that the builder implementation can vary on the specific use case. Sometimes a builder is combined with factories. As far as I can see almost everyone interpreted it in a different way, but I don’t think that’s a problem.
You can reach out to me at:
Linkedin: Aaina Jain