Builder Design Pattern: A Comprehensive Guide with C# Code Examples

The Builder Design Pattern is a creational design pattern that separates the construction of complex objects from their representation, enabling developers to create different representations of the same object using the same construction process. 

Builder Design Pattern
Builder Design Pattern

This blog post will cover the basics of the Builder Design Pattern, including its structure, advantages, and disadvantages. We’ll also provide a detailed code example in C# to help you understand how to implement this pattern in your projects.

Builder Design Pattern 

The Builder Design Pattern is a creational pattern that separates the construction of complex objects from their representation, allowing developers to create different representations of the same object using the same construction process.

This pattern is used when you need to create objects with many optional attributes or when you need to create objects with different representations.

UML Diagram of Builder Design Pattern

The UML diagram of the Builder Design Pattern consists of four main components: Product, Builder, ConcreteBuilder, and Director.

  • Product: The Product is the final object that the Builder Design Pattern creates. It contains all the attributes that are necessary for the object to function.
  • Builder: The Builder is an interface that specifies how to create the Product. It defines all the methods that are required to create the Product.
  • ConcreteBuilder: The ConcreteBuilder is an implementation of the Builder interface. It contains all the methods required to create the Product. The ConcreteBuilder is responsible for constructing the Product and returning it to the client.
  • Director: The Director is responsible for managing the creation of the Product. It uses the Builder interface to construct the Product. The Director knows the exact steps that are required to build the Product.
UML Diagram of Builder Design Pattern
UML Diagram of Builder Design Pattern

Example of Builder Design Pattern in C#

Now, let’s take a look at an example of how to implement the Builder Design Pattern in C#. In this example, we will create a Pizza object using the Builder Design Pattern.

First, let’s create the Product class (Pizza):

public class Pizza
{
    private string _dough = "";
    private string _sauce = "";
    private string _topping = "";

    public void SetDough(string dough)
    {
        this._dough = dough;
    }

    public void SetSauce(string sauce)
    {
        this._sauce = sauce;
    }

    public void SetTopping(string topping)
    {
        this._topping = topping;
    }
}

Next, let’s create the Builder interface(IPizzaBuilder):

public interface IPizzaBuilder
{
    void SetDough();
    void SetSauce();
    void SetTopping();
    Pizza GetPizza();
}

Now, let’s create the ConcreteBuilder class(HawaiianPizzaBuilder):

public class HawaiianPizzaBuilder : IPizzaBuilder
{
    private Pizza _pizza = new Pizza();

    public void SetDough()
    {
        this._pizza.SetDough("cross");
    }

    public void SetSauce()
    {
        this._pizza.SetSauce("mild");
    }

    public void SetTopping()
    {
        this._pizza.SetTopping("ham+pineapple");
    }

    public Pizza GetPizza()
    {
        return this._pizza;
    }
}

Finally, let’s create the Director class (Waiter):

public class Waiter
{
    private IPizzaBuilder _pizzaBuilder;

    public void SetPizzaBuilder(IPizzaBuilder pizzaBuilder)
    {
        this._pizzaBuilder = pizzaBuilder;
    }

    public Pizza GetPizza()
    {
        return this._pizzaBuilder.GetPizza();
    }

    public void ConstructPizza()
    {
        this._pizzaBuilder.SetDough();
        this._pizzaBuilder.SetSauce();
        this._pizzaBuilder.SetTopping();
    }
}

Advantages of Builder Design Pattern

The Builder Design Pattern has several advantages, including:

  1. Separation of Concerns: The Builder Design Pattern separates the construction of complex objects from their representation, which allows for more control over the creation process. This separation also makes changing an object’s representation easier without changing its construction process.
  2. Flexibility: The Builder Design Pattern allows developers to create different representations of the same object using the same construction process. This flexibility can save time and effort when creating objects with many optional attributes or when creating objects with different representations.
  3. Code Reusability: The Builder Design Pattern can help improve code reusability. The construction process for a complex object is defined in a single place, which can be reused across multiple projects.
  4. Encapsulation: The Builder Design Pattern encapsulates the construction process of a complex object, which can help make the code more maintainable and easier to read.

Disadvantages of Builder Design Pattern

 The Builder Design Pattern also has some disadvantages, including:

  1. Increased Complexity: The Builder Design Pattern can add complexity to the codebase. It requires the creation of multiple classes, which can be difficult to manage and maintain.
  2. Increased Code Overhead: The Builder Design Pattern can increase code overhead. It requires the creation of additional classes, which can increase the size of the codebase.
  3. Performance Overhead: The Builder Design Pattern can result in performance overhead. It requires the creation of additional objects, which can impact the application’s performance.

Example 2:

Here is another example of Builder Design Pattern:

using System;
// Product class
class Product
{
    private string _partA;
    private string _partB;
    private string _partC;

    public void SetPartA(string part)
    {
        _partA = part;
    }

    public void SetPartB(string part)
    {
        _partB = part;
    }

    public void SetPartC(string part)
    {
        _partC = part;
    }

    public void Show()
    {
        Console.WriteLine($"Part A: {_partA}");
        Console.WriteLine($"Part B: {_partB}");
        Console.WriteLine($"Part C: {_partC}");
    }
}

// Builder interface
interface IBuilder
{
    void BuildPartA();
    void BuildPartB();
    void BuildPartC();
    Product GetProduct();
}

// ConcreteBuilder class
class ConcreteBuilder : IBuilder
{
    private readonly Product _product = new Product();

    public void BuildPartA()
    {
        _product.SetPartA("Part A");
    }

    public void BuildPartB()
    {
        _product.SetPartB("Part B");
    }

    public void BuildPartC()
    {
        _product.SetPartC("Part C");
    }

    public Product GetProduct()
    {
        return _product;
    }
}

// Director class
class Director
{
    public void Construct(IBuilder builder)
    {
        builder.BuildPartA();
        builder.BuildPartB();
        builder.BuildPartC();
    }
}
class Program
{
    // Main method
    static void Main(string[] args)
    {
        var director = new Director();
        var builder = new ConcreteBuilder();

        director.Construct(builder);

        var product = builder.GetProduct();

        product.Show();

        // Output:
        // Part A: Part A
        // Part B: Part B
        // Part C: Part C
    }
}

Output:

Builder design pattern code example result

This code creates a Product object using the ConcreteBuilder and Director classes. The Director class constructs the Product using the IBuilder interface, which the ConcreteBuilder class implements. Finally, the Product is displayed using the Show method.

References: Wikipedia-Builder Design Pattern

Conclusion:

The Builder Design Pattern is a useful creational pattern that can help to improve code quality, reusability, and maintainability.

It separates the construction of complex objects from their representation, enabling developers to create different representations of the same object using the same construction process. While the Builder Design Pattern has some disadvantages, its benefits often outweigh the costs.

This pattern allows developers to easily create complex objects and improve their code’s overall quality.

In this post, we covered the basics of the Builder Design Pattern, including its structure, advantages, and disadvantages. We also provided a detailed code example in C# to help you understand how to implement this pattern in your projects. This post helped you to understand the Builder Design Pattern and its usefulness in creating complex objects.

FAQs

Q: What is the Builder Design Pattern?

The Builder Design Pattern is a creational design pattern that separates the construction of a complex object from its representation, allowing the same construction process to create different representations.

Q: When should you use the Builder Design Pattern?

The Builder Design Pattern is useful when creating objects with complex initialization processes requiring multiple steps or optional parameters.

Q: What are the benefits of using the Builder Design Pattern?

The Builder Design Pattern provides several benefits, such as simplifying object creation, making code more readable, and increasing flexibility in object creation.

Q: What is the difference between the Builder Design Pattern and the Factory Design Pattern?

The Factory Design Pattern is a creational pattern that provides an interface for creating objects in a superclass but allows subclasses to alter the type of objects that will be created.

The Builder Design Pattern separates the construction of a complex object from its representation, whereas the Factory Design Pattern does not.

Q: What is the difference between the Builder Design Pattern and the Abstract Factory Design Pattern?

The Abstract Factory Design Pattern is a creational pattern that provides an interface for creating families of related or dependent objects without specifying their concrete classes.

The Builder Design Pattern focuses on creating a single complex object, whereas the Abstract Factory Design Pattern creates families of related or dependent objects.

Q: Is the Builder Design Pattern used in popular frameworks or libraries?

The Builder Design Pattern is used in many popular frameworks and libraries, such as the .NET Framework, the Java Persistence API, and the Apache HttpClient library.

Articles you might also like:

We would love to hear your thoughts on this post. Please leave a comment below and share it with others.

Shekh Ali
4 1 vote
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments