Builder Pattern

Understand the Builder Pattern with detailed examples, C# and Python source code, and real-world use cases. Learn to construct complex objects step by step with ease.

๐Ÿงฑ Builder Pattern โ€“ Step-by-Step Construction

The Builder Pattern is a creational design pattern that allows step-by-step construction of complex objects. It separates the construction of a complex object from its representation so the same construction process can create different representations.

๐Ÿงฉ When to Use

  • When object creation involves many steps or optional fields.
  • When you need different representations of an object (e.g., HTML vs JSON).
  • When constructors become overloaded with many parameters.

๐Ÿ”Š Example 1: Building a Meal (Burger, Drink, etc.)

Problem: You want to build a meal that may contain different items like burger, drink, fries, etc. Using constructors gets messy.

Solution: Use Builder to add items step by step.


public class Meal
{
    public string Main { get; set; }
    public string Drink { get; set; }
    public string Side { get; set; }

    public override string ToString() =>
        $"Main: {Main}, Drink: {Drink}, Side: {Side}";
}

public class MealBuilder
{
    private Meal meal = new Meal();

    public MealBuilder AddMain(string main)
    {
        meal.Main = main;
        return this;
    }

    public MealBuilder AddDrink(string drink)
    {
        meal.Drink = drink;
        return this;
    }

    public MealBuilder AddSide(string side)
    {
        meal.Side = side;
        return this;
    }

    public Meal Build() => meal;
}

// Usage
var meal = new MealBuilder()
              .AddMain("Burger")
              .AddDrink("Coke")
              .AddSide("Fries")
              .Build();

Console.WriteLine(meal);
      

class Meal:
    def __init__(self):
        self.main = None
        self.drink = None
        self.side = None

    def __str__(self):
        return f"Main: {self.main}, Drink: {self.drink}, Side: {self.side}"

class MealBuilder:
    def __init__(self):
        self.meal = Meal()

    def add_main(self, main):
        self.meal.main = main
        return self

    def add_drink(self, drink):
        self.meal.drink = drink
        return self

    def add_side(self, side):
        self.meal.side = side
        return self

    def build(self):
        return self.meal

# Usage
meal = MealBuilder().add_main("Burger").add_drink("Coke").add_side("Fries").build()
print(meal)
      

๐Ÿงฑ Example 2: Director with Multiple Builders

Scenario: You want to create different types of houses using the same steps โ€” foundation, walls, roof.


public class House
{
    public string Foundation { get; set; }
    public string Walls { get; set; }
    public string Roof { get; set; }

    public override string ToString() => 
        $"Foundation: {Foundation}, Walls: {Walls}, Roof: {Roof}";
}

public abstract class HouseBuilder
{
    protected House house = new House();
    public abstract void BuildFoundation();
    public abstract void BuildWalls();
    public abstract void BuildRoof();
    public House GetResult() => house;
}

public class WoodenHouseBuilder : HouseBuilder
{
    public override void BuildFoundation() => house.Foundation = "Wood Poles";
    public override void BuildWalls() => house.Walls = "Wood Panels";
    public override void BuildRoof() => house.Roof = "Wooden Shingles";
}

public class Director
{
    public void Construct(HouseBuilder builder)
    {
        builder.BuildFoundation();
        builder.BuildWalls();
        builder.BuildRoof();
    }
}

// Usage
var builder = new WoodenHouseBuilder();
var director = new Director();
director.Construct(builder);
Console.WriteLine(builder.GetResult());
      

class House:
    def __init__(self):
        self.foundation = None
        self.walls = None
        self.roof = None

    def __str__(self):
        return f"Foundation: {self.foundation}, Walls: {self.walls}, Roof: {self.roof}"

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

    def build_foundation(self): pass
    def build_walls(self): pass
    def build_roof(self): pass

    def get_result(self):
        return self.house

class WoodenHouseBuilder(HouseBuilder):
    def build_foundation(self):
        self.house.foundation = "Wood Poles"

    def build_walls(self):
        self.house.walls = "Wood Panels"

    def build_roof(self):
        self.house.roof = "Wooden Shingles"

class Director:
    def construct(self, builder):
        builder.build_foundation()
        builder.build_walls()
        builder.build_roof()

# Usage
builder = WoodenHouseBuilder()
director = Director()
director.construct(builder)
print(builder.get_result())
      

๐Ÿ“Œ Key Points

FeatureDescription
Pattern TypeCreational
Key ParticipantsBuilder, Product, Director
Fluent InterfaceImproves readability by chaining methods
BenefitSeparate construction from representation

๐Ÿงช Quiz: Test Your Understanding