👉🏼 Click here to Join I ❤️ .NET WhatsApp Channel to get 🔔 notified about new articles and other updates.
Creational Design Pattern - Builder

Creational Design Pattern - Builder

Author - Abdul Rahman (Bhai)

Design Pattern

13 Articles

Improve

Table of Contents

  1. What we gonna do?
  2. Why we gonna do?
  3. How we gonna do?
  4. Summary

What we gonna do?

In this article, let's learn about Builder Design Pattern in .NET.

Embarking on the journey of software design often involves constructing complex objects with varying representations. One tool in our design toolkit that excels at this task is the Builder Pattern. As a creational pattern, it gracefully tackles the challenge of creating intricate objects by separating their construction from their representation.

In this exploration, we'll delve into the structure, use cases, advantages, and disadvantages of the Builder Pattern, accompanied by real-life examples.

Why we gonna do?

When constructing objects with many parameters, developers often resort to telescoping constructors — creating multiple constructor overloads with different combinations of parameters. This quickly becomes unmanageable and error-prone as the number of optional parameters grows.

Step-by-step construction without a pattern can also lead to inconsistent intermediate states, where an object is partially initialized and in an invalid state before all required parts are set.

The Builder Pattern solves both problems by separating the construction process from the final representation. A director orchestrates the steps, concrete builders assemble the parts, and the product is only returned when fully constructed — resulting in cleaner, more readable, and maintainable code.

How we gonna do?

Structure

At the core of the Builder Pattern lies a structured framework that facilitates the step-by-step construction of complex objects. The fundamental components include:


// Builder Interface
public interface ICarBuilder
{
    void BuildEngine();
    void BuildFrame();
}

// Concrete Builders
public class BMWBuilder : ICarBuilder
{
    private Car _car;

    public BMWBuilder()
    {
        _car = new Car("BMW");
    }

    public void BuildEngine()
    {
        _car.AddPart("High-performance BMW Engine");
    }

    public void BuildFrame()
    {
        _car.AddPart("Sturdy BMW Frame");
    }
}

public class MiniBuilder : ICarBuilder
{
    private Car _car;

    public MiniBuilder()
    {
        _car = new Car("Mini");
    }

    public void BuildEngine()
    {
        _car.AddPart("Efficient Mini Engine");
    }

    public void BuildFrame()
    {
        _car.AddPart("Compact Mini Frame");
    }
}

// Product
public class Car
{
    private string _type;
    private List<string> _parts = new List<string>();

    public Car(string type)
    {
        _type = type;
    }

    public void AddPart(string part)
    {
        _parts.Add(part);
    }

    public override string ToString()
    {
        return $"{_type} - Parts: {string.Join(", ", _parts)}";
    }
}

// Director
public class Garage
{
    private ICarBuilder _builder;

    public void Construct(ICarBuilder builder)
    {
        _builder = builder;
        _builder.BuildEngine();
        _builder.BuildFrame();
    }
}
            

In the above code, Builder Interface is an abstract interface defining the creation of parts for the product object. In our analogy, this is akin to a car builder interface, outlining methods like buildEngine and buildFrame.

Concrete Builders is an Implementations of the builder interface, such as the BMW and Mini builders. These class'es assemble the product and keep track of its representation, providing a method to retrieve the final product.

Product is the complex object under construction, represented by the car in our example. It may include constituent parts like a frame or an engine. Director is the entity responsible for constructing the object using the builder interface. In our analogy, think of a garage orchestrating the construction of cars.

Note: The builder can be implemented using interface or abstract class.

Demo Space

Use Cases

  • Algorithm Independence - When you want the algorithm for creating a complex object independent of its parts and assembly process.
  • Diverse Representations - When the construction process should allow for different representations of the same object, like building distinct cars using the same construction process.
  • Other Real-world applications include generating documents, constructing database queries, designing game characters, and creating user interfaces or forms.

Advantages

  • Internal Representation Variability - Enables variation in the internal representation of the product by providing a new builder.
  • Isolation of Construction and Representation Code - Enhances modularity by encapsulating the construction and representation details, following the Single Responsibility Principle.
  • Fine-grained Construction Control - Allows finer control over the construction process with step-by-step creation.

Disadvantages

While powerful, the Builder Pattern introduces complexity to the codebase due to the creation of multiple classes. It's crucial to balance the benefits with the increased complexity.

  • Abstract Factory pattern
  • Composite pattern

Summary

In the vast landscape of software design, the Builder Pattern stands as a reliable guide for constructing complex objects with elegance and flexibility. Its ability to separate construction from representation empowers developers to navigate the intricacies of design, providing a valuable tool for crafting robust and maintainable software.

👉🏼 Click here to Join I ❤️ .NET WhatsApp Channel to get 🔔 notified about new articles and other updates.
  • Design Pattern
  • Creational
  • Builder