0
0
LLDsystem_design~7 mins

Builder pattern in LLD - System Design Guide

Choose your learning style9 modes available
Problem Statement
Creating complex objects with many optional parts using a single constructor or multiple setters leads to confusing code and errors. It becomes hard to ensure the object is always in a valid state, and the construction process is not clear or flexible.
Solution
The Builder pattern separates the construction of a complex object from its representation. It uses a step-by-step approach where a builder class constructs the object piece by piece, allowing different representations and ensuring the object is built correctly before use.
Architecture
┌─────────────┐       ┌───────────────┐       ┌───────────────┐
│   Director  │──────▶│    Builder    │──────▶│    Product    │
└─────────────┘       └───────────────┘       └───────────────┘
       │                    ▲                      ▲
       │                    │                      │
       │                    │                      │
       └────────────────────┴──────────────────────┘

This diagram shows the Director controlling the Builder to create a Product step-by-step. The Builder defines construction steps, and the Product is the final complex object.

Trade-offs
✓ Pros
Separates complex object construction from its representation, improving code clarity.
Allows step-by-step construction and different representations of the object.
Ensures the object is always in a valid state before use.
Improves maintainability by isolating construction logic.
✗ Cons
Adds extra classes and complexity for simple objects.
Requires more code and understanding of the pattern.
May be overkill for objects with few optional parts.
Use when creating complex objects with many optional parts or configurations, especially when construction steps must be controlled or varied.
Avoid when objects are simple or have only a few parameters, where constructors or setters are sufficient.
Real World Examples
Google
Uses Builder pattern in Protocol Buffers to construct complex message objects with optional fields safely and clearly.
Amazon
Applies Builder pattern in AWS SDKs to build requests with many optional parameters for services like S3 and EC2.
Netflix
Uses Builder pattern to configure complex streaming session objects with multiple optional settings.
Code Example
The before code shows a constructor with optional parameters, which can get confusing with many options. The after code uses a Builder class to set parts step-by-step, making construction clear and flexible.
LLD
### Before (without Builder pattern):
class House:
    def __init__(self, windows=None, doors=None, roof=None):
        self.windows = windows
        self.doors = doors
        self.roof = roof

# Creating a house with many optional parts
house = House(windows=4, doors=2)


### After (with Builder pattern):
class House:
    def __init__(self):
        self.windows = 0
        self.doors = 0
        self.roof = None

class HouseBuilder:
    def __init__(self):
        self.house = House()

    def add_windows(self, count):
        self.house.windows = count
        return self

    def add_doors(self, count):
        self.house.doors = count
        return self

    def add_roof(self, style):
        self.house.roof = style
        return self

    def build(self):
        return self.house

# Using builder to create a house step-by-step
builder = HouseBuilder()
house = builder.add_windows(4).add_doors(2).add_roof('Gable').build()
OutputSuccess
Alternatives
Factory pattern
Creates objects in one step without step-by-step construction or complex configuration.
Use when: Use when object creation is simple and does not require multiple construction steps.
Prototype pattern
Creates new objects by cloning existing ones rather than building from scratch.
Use when: Use when you need to create many similar objects quickly by copying.
Summary
Builder pattern helps create complex objects step-by-step with clear construction logic.
It separates object construction from representation, improving code clarity and flexibility.
It is best used when objects have many optional parts or configurations.