Builder Design Patten in C#

The Builder Design Pattern is a creational design pattern that separates the construction of a complex object from its representation. It provides a way to construct an object step by step. This pattern is useful when an object has many optional components or configurations, and you want to create different variations of the same object.

Here’s a C# example of the Builder Design Pattern with a use case for building different types of computer systems:

Create the Product Class

Define the complex object (the product) that you want to build. In this example, we’ll create a Computer class with various components.

public class Computer
{
    public string CPU { get; set; }
    public string RAM { get; set; }
    public string Storage { get; set; }
    public string GraphicsCard { get; set; }

    public override string ToString()
    {
        return $"CPU: {CPU}, RAM: {RAM}, Storage: {Storage}, GPU: {GraphicsCard}";
    }
}

Create the Builder Interface

Define an interface that declares the steps to construct the product.

public interface IComputerBuilder
{
    void SetCPU();
    void SetRAM();
    void SetStorage();
    void SetGraphicsCard();
    Computer Build();
}

Create Concrete Builders

Implement the builder interface with concrete builder classes, each responsible for building a specific type of computer system.

public class GamingComputerBuilder : IComputerBuilder
{
    private Computer computer = new Computer();

    public void SetCPU()
    {
        computer.CPU = "Intel Core i9";
    }

    public void SetRAM()
    {
        computer.RAM = "32GB DDR4";
    }

    public void SetStorage()
    {
        computer.Storage = "1TB SSD";
    }

    public void SetGraphicsCard()
    {
        computer.GraphicsCard = "NVIDIA RTX 3090";
    }

    public Computer Build()
    {
        return computer;
    }
}

public class OfficeComputerBuilder : IComputerBuilder
{
    private Computer computer = new Computer();

    public void SetCPU()
    {
        computer.CPU = "Intel Core i5";
    }

    public void SetRAM()
    {
        computer.RAM = "16GB DDR4";
    }

    public void SetStorage()
    {
        computer.Storage = "256GB SSD";
    }

    public void SetGraphicsCard()
    {
        computer.GraphicsCard = "Integrated Graphics";
    }

    public Computer Build()
    {
        return computer;
    }
}

Create the Director (Optional)

Optionally, you can create a director class that orchestrates the building process if constructing objects requires a specific order or additional steps.

Use Case – Building Computers

class Program
{
    static void Main(string[] args)
    {
        IComputerBuilder gamingComputerBuilder = new GamingComputerBuilder();
        IComputerBuilder officeComputerBuilder = new OfficeComputerBuilder();

        Computer gamingComputer = gamingComputerBuilder
            .SetCPU()
            .SetRAM()
            .SetStorage()
            .SetGraphicsCard()
            .Build();

        Computer officeComputer = officeComputerBuilder
            .SetCPU()
            .SetRAM()
            .SetStorage()
            .SetGraphicsCard()
            .Build();

        Console.WriteLine("Gaming Computer Configuration:");
        Console.WriteLine(gamingComputer);

        Console.WriteLine("\nOffice Computer Configuration:");
        Console.WriteLine(officeComputer);
    }
}

In this example, the Builder Design Pattern allows you to create different configurations of computer systems (gaming and office) step by step. Each builder specifies the details for a particular type of computer, and the client code constructs the product by selecting the appropriate builder. This pattern is useful when you need to create complex objects with varying configurations and when you want to ensure that the object’s construction process is separate from its representation.