Bird
Raised Fist0
LLDsystem_design~7 mins

Builder pattern in LLD - System Design Guide

Choose your learning style10 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.

Practice

(1/5)
1. What is the main purpose of the Builder pattern in system design?
easy
A. To construct complex objects step by step, separating construction from representation
B. To enforce a single instance of a class throughout the system
C. To provide a way to access elements of a collection sequentially
D. To define a family of algorithms and make them interchangeable

Solution

  1. Step 1: Understand Builder pattern purpose

    The Builder pattern is designed to create complex objects step by step, allowing different representations.
  2. Step 2: Compare with other patterns

    Options A, C, and D describe Singleton, Iterator, and Strategy patterns respectively, not Builder.
  3. Final Answer:

    To construct complex objects step by step, separating construction from representation -> Option A
  4. Quick Check:

    Builder pattern = stepwise construction [OK]
Hint: Builder pattern builds complex objects stepwise [OK]
Common Mistakes:
  • Confusing Builder with Singleton pattern
  • Thinking Builder manages object access, not construction
  • Mixing Builder with Strategy or Iterator patterns
2. Which of the following is the correct way to implement method chaining in a Builder class?
easy
A. Each setter method returns a new Builder instance every time
B. Each setter method returns void and does not return anything
C. Each setter method returns the final built object immediately
D. Each setter method returns this (the builder instance) to allow chaining

Solution

  1. Step 1: Understand method chaining in Builder

    Method chaining requires each setter to return the builder instance (this) so calls can be chained.
  2. Step 2: Analyze other options

    Returning void breaks chaining; returning new builder instances is inefficient; returning final object ends chain prematurely.
  3. Final Answer:

    Each setter method returns this (the builder instance) to allow chaining -> Option D
  4. Quick Check:

    Method chaining = return this [OK]
Hint: Return 'this' in setters for chaining [OK]
Common Mistakes:
  • Returning void and expecting chaining
  • Creating new builder instances in setters
  • Returning final object too early
3. Given the following Builder usage code, what will be the output?
class House {
  constructor(walls, doors) {
    this.walls = walls;
    this.doors = doors;
  }
  describe() {
    return `House with ${this.walls} walls and ${this.doors} doors.`;
  }
}

class HouseBuilder {
  constructor() {
    this.walls = 0;
    this.doors = 0;
  }
  setWalls(count) {
    this.walls = count;
    return this;
  }
  setDoors(count) {
    this.doors = count;
    return this;
  }
  build() {
    return new House(this.walls, this.doors);
  }
}

const house = new HouseBuilder().setWalls(4).setDoors(2).build();
console.log(house.describe());
medium
A. House with 4 walls and 2 doors.
B. House with 0 walls and 0 doors.
C. House with 2 walls and 4 doors.
D. Error: setWalls and setDoors do not return builder

Solution

  1. Step 1: Trace method calls and values

    The builder sets walls to 4 and doors to 2, then builds a House with these values.
  2. Step 2: Check describe output

    The describe method returns a string with walls and doors values, so output is 'House with 4 walls and 2 doors.'
  3. Final Answer:

    House with 4 walls and 2 doors. -> Option A
  4. Quick Check:

    Builder sets walls=4, doors=2 [OK]
Hint: Follow method chain values stepwise [OK]
Common Mistakes:
  • Mixing walls and doors values
  • Assuming setters don't return builder
  • Ignoring build() method output
4. Identify the error in this Builder pattern implementation:
class CarBuilder {
  constructor() {
    this.color = '';
  }
  setColor(color) {
    this.color = color;
  }
  build() {
    return { color: this.color };
  }
}

const car = new CarBuilder().setColor('red').build();
console.log(car.color);
medium
A. build method returns wrong object type
B. setColor does not return the builder instance, so chaining fails
C. Constructor does not initialize color properly
D. No error, code works fine

Solution

  1. Step 1: Check method chaining in setColor

    setColor does not return this, so chaining to build() fails.
  2. Step 2: Analyze consequences

    Because setColor returns undefined, calling build() immediately after causes an error or unexpected behavior.
  3. Final Answer:

    setColor does not return the builder instance, so chaining fails -> Option B
  4. Quick Check:

    Missing 'return this' breaks chaining [OK]
Hint: Setters must return 'this' for chaining [OK]
Common Mistakes:
  • Ignoring missing return in setter
  • Thinking build returns wrong type
  • Assuming constructor error
5. You need to design a system to build customizable computer configurations with optional components like GPU, RAM, and Storage. Which Builder pattern approach best supports this requirement?
hard
A. Build the computer object directly without a builder, setting all fields in constructor
B. Use multiple Builder classes, each building a fixed configuration without chaining
C. Create a single Builder class with methods for each optional component, returning the builder for chaining
D. Use a factory method that returns pre-built fixed configurations only

Solution

  1. Step 1: Analyze requirement for optional components

    Optional components require flexible, stepwise construction with chaining for readability.
  2. Step 2: Evaluate options

    Create a single Builder class with methods for each optional component, returning the builder for chaining supports chaining and optional parts; B lacks chaining and flexibility; C is inflexible; D only returns fixed configs.
  3. Final Answer:

    Create a single Builder class with methods for each optional component, returning the builder for chaining -> Option C
  4. Quick Check:

    Flexible builder with chaining fits optional parts [OK]
Hint: Use one builder with chaining for optional parts [OK]
Common Mistakes:
  • Using multiple builders without chaining
  • Setting all options in constructor (inflexible)
  • Relying on fixed pre-built configurations only
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard