Back to Overview

Builder Pattern

The Builder Pattern is a creational design pattern that lets you construct complex objects step by step. It allows you to produce different types and representations of an object using the same construction code.

Problem

Imagine you're creating a class to build houses. A minimal house might just have four walls, a floor, a roof, and a door. But what if some houses also need a garage, a swimming pool, a garden, or various other optional components?

You could use a constructor with many parameters, but this leads to a "telescoping constructor" with many combinations of parameters. Alternatively, you could use setters for optional parameters, but this approach leads to incomplete objects if a required setter is not called.

Director Builder buildPartA() buildPartB() buildPartC() ConcreteBuilder1 ConcreteBuilder2 Product1 Product2 uses creates creates Client configures uses getResult() getResult()

Components

Implementation Example

Here's a basic implementation of the Builder pattern in JavaScript for building a house:

// Product
class House {
    constructor() {
        this.floors = 0;
        this.walls = 0;
        this.windows = 0;
        this.doors = 0;
        this.hasGarage = false;
        this.hasSwimmingPool = false;
        this.hasGarden = false;
        this.hasStatues = false;
    }
    
    getDescription() {
        let description = `This house has ${this.floors} floor(s), ${this.walls} walls, ${this.windows} windows, and ${this.doors} door(s).`;
        
        if (this.hasGarage) description += " It has a garage.";
        if (this.hasSwimmingPool) description += " It has a swimming pool.";
        if (this.hasGarden) description += " It has a garden.";
        if (this.hasStatues) description += " It has decorative statues.";
        
        return description;
    }
}

// Builder Interface
class HouseBuilder {
    reset() {
        this.house = new House();
        return this;
    }
    
    buildFloors(count) {
        this.house.floors = count;
        return this;
    }
    
    buildWalls(count) {
        this.house.walls = count;
        return this;
    }
    
    buildWindows(count) {
        this.house.windows = count;
        return this;
    }
    
    buildDoors(count) {
        this.house.doors = count;
        return this;
    }
    
    buildGarage() {
        this.house.hasGarage = true;
        return this;
    }
    
    buildSwimmingPool() {
        this.house.hasSwimmingPool = true;
        return this;
    }
    
    buildGarden() {
        this.house.hasGarden = true;
        return this;
    }
    
    buildStatues() {
        this.house.hasStatues = true;
        return this;
    }
    
    getResult() {
        return this.house;
    }
}

// Director
class HouseDirector {
    constructor(builder) {
        this.builder = builder;
    }
    
    setBuilder(builder) {
        this.builder = builder;
    }
    
    constructMinimalHouse() {
        return this.builder
            .reset()
            .buildFloors(1)
            .buildWalls(4)
            .buildWindows(2)
            .buildDoors(1)
            .getResult();
    }
    
    constructLuxuryHouse() {
        return this.builder
            .reset()
            .buildFloors(3)
            .buildWalls(12)
            .buildWindows(10)
            .buildDoors(3)
            .buildGarage()
            .buildSwimmingPool()
            .buildGarden()
            .buildStatues()
            .getResult();
    }
}

// Client code
const builder = new HouseBuilder();
const director = new HouseDirector(builder);

// Construct a minimal house using the director
const minimalHouse = director.constructMinimalHouse();
console.log(minimalHouse.getDescription());

// Construct a luxury house using the director
const luxuryHouse = director.constructLuxuryHouse();
console.log(luxuryHouse.getDescription());

// Construct a custom house directly with the builder
const customHouse = builder
    .reset()
    .buildFloors(2)
    .buildWalls(8)
    .buildWindows(4)
    .buildDoors(2)
    .buildGarage()
    .buildGarden()
    .getResult();
console.log(customHouse.getDescription());

When to Use

Benefits

Real-World Uses

Interactive Demo: Car Builder

This demo demonstrates how the Builder pattern allows you to create complex objects step by step. Configure a car with various options and see the resulting object.

Basic Details

Exterior Features

Interior Features

Safety Features

Car Specifications

  • Select options and click "Build Car" to see the result
// Car Builder demonstration log will appear here