Friday, January 3, 2025
Builder

Updated: May 2025
π Brief
The Builder pattern is a creational design pattern ποΈ that separates the construction of a complex object from its representation. This allows for creating different representations of an object using the same construction process.
β Problem
The Builder pattern solves two key problems:
-
ποΈ Managing complex object creation.
Complex objects often require detailed, step-by-step initialization of multiple fields and nested objects. This initialization is typically buried inside:
- A large, unwieldy constructor with too many parameters (commonly referred to as the "telescoping constructor" problem).
- Or worse, scattered across the client code, making it hard to read, maintain, or debug.
The Builder pattern organizes this process into manageable steps.
-
π Creating different representations.
Sometimes, you need different versions of the same object with varying configurations. one might try creating multiple subclasses to cover all possible variations. This approach becomes unmanageable when:
- New features or parameters are introduced (e.g., adding a swimming pool or porch style to a house).
- Every combination of parameters leads to a growing hierarchy of subclasses.
The Builder pattern simplifies this by encapsulating the construction logic.
π‘ Solution
Letβs explore how the Builder pattern achieves flexibility and clarity:
-
Define a Builder Interface:
The first step is to define a blueprint for building objects. This interface provides the structure for the steps needed to assemble an object. It ensures that all concrete builders follow the same process. -
Implement Concrete Builders:
Concrete builders implement the defined steps to construct specific object variations. This allows for creating different configurations or representations of the object. -
Direct the Building Process:
A director class orchestrates the building process. It ensures that builders follow the correct sequence of steps while allowing customization of the process. -
Simplify Object Construction:
The client code interacts with the director or builder to request specific configurations, abstracting away the complexity of the construction process.
π Blueprint
π οΈ Implementation & Analysis
Note:
-
A Standard Builder approach uses discrete methods to set object properties step by step, offering clarity and simplicity.
-
The Fluent Builder style chains method calls for a more concise and readable configuration. This approach is especially helpful when constructing objects with many configurable attributes.
-
Define Builder Interface: Create a base interface or abstract class with methods for setting the components of the object. This ensures that all concrete builders follow a consistent structure.
-
Concrete Builders: Implement the builder interface in classes tailored to create specific configurations or representations of the object. These builders encapsulate the construction logic.
-
Director Role: Introduce a director class to control the sequence of steps for creating the object. While optional, this ensures consistency when assembling complex objects.
For simpler use cases, the client can directly interact with the builder without requiring a director.
-
Client Code Integration: Use the builder or director to construct objects. This separates the construction logic from the object itself, improving code maintainability and flexibility.
Let's understand with an example.
In this example, weβll implement a Meal Builder using the Builder pattern. The Builder pattern helps us construct complex objects step-by-step. Our goal is to create a Meal that consists of multiple items (like a Burger and a Drink) while keeping the construction process independent of the actual meal structure.
Step 1: Defining the Product
The "product" in the Builder pattern is the object being built. In our example, itβs the Meal
.
AddItem
: Adds an item to the meal.ShowItems
: Displays all the items in the meal.
Step 2: Creating the Builder Interface
The Builder interface defines the steps required to build a meal. Each concrete builder will implement this interface to provide specific implementations for the steps.
AddBurger
andAddDrink
: These methods define the steps for adding items to the meal.GetMeal
: Returns the constructedMeal
.
Step 3: Implementing Concrete Builders
Letβs create two concrete builders: VegMealBuilder
for vegetarian meals and NonVegMealBuilder
for non-vegetarian meals.
Step 4: Creating the Director (Optional)
The Director is responsible for managing the construction process. It uses a builder to construct a Meal
step-by-step.
Step 5: Using the Builder Pattern in the Main Function
Now, letβs see the Builder pattern in action in the main
function.
What Happens Here?
- We create two builders:
VegMealBuilder
andNonVegMealBuilder
. - The
Director
orchestrates the construction process using the builder set viaSetBuilder
. - The constructed meals are retrieved using
GetMeal
and displayed usingShowItems
.
π§βπ» Putting It All Together
Hereβs the complete Builder implementation:
βοΈ Pros & Cons
π Pros | ππ» Cons |
---|---|
You can be sure that a class has only a single instance. | Violates the Single Responsibility Principle. The pattern solves two problems at the time. |
π When to Use
- Objects require numerous configuration steps or optional parameters.
- Different representations of an object are needed with minimal effort.
However, if your object is simple and doesnβt involve many parameters, the Builder pattern may add unnecessary complexity.