C#: Builder

Builder

Builder is a creational design pattern, which allows constructing complex objects step by step.

Unlike other creational patterns, Builder does not require products to have a common interface. That makes it possible to produce different products using the same construction process.

More about Builder

Application of the pattern in C#

Complexity:

Popularity:

Usage examples: The Builder pattern is a well-known pattern in C# world. It is especially useful when you need to create an object with lots of possible configuration options.

Identification: The Builder pattern can be recognized in class, which has a single creational method and several methods to configure the resulting object. Builder methods often support chaining (for example, someBuilder->setValueA(1)->setValueB(2)->create()).

Example: Structure of the Pattern

This example illustrates the structure of the Builder design pattern. It focuses on answering these questions:

  • What classes does it consists of?
  • What roles do these classes play?
  • In what way the elements of the pattern are related?

Program.cs: Structural Example

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RefactoringGuru.DesignPatterns.Builder.Structural
{
    class Program
    {
        static void Main(string[] args)
        {
            Builder builder = new ConcreteBuilder();
            Director director = new Director(builder);

            Client client = new Client();
            client.ClientCode(director, builder);
        }
    }

    public class Client
    {
        public void ClientCode(Director director, Builder builder)
        {
            Console.WriteLine("Standart basic product:");
            director.buildMinimalViableProduct();
            Console.WriteLine(builder.GetProduct().ListParts());

            Console.WriteLine("Standart full featured product:");
            director.buildFullFeaturedProduct();
            Console.WriteLine(builder.GetProduct().ListParts());

            Console.WriteLine("Custom product:");
            builder.BuildPartA();
            builder.BuildPartC();
            Console.WriteLine(builder.GetProduct().ListParts());
        }
    }

    public class Director
    {
        Builder builder;

        public Director(Builder builder)
        {
            this.builder = builder;
        }

        public void buildMinimalViableProduct()
        {
            builder.BuildPartA();
        }
		
        public void buildFullFeaturedProduct()
        {
            builder.BuildPartA();
            builder.BuildPartB();
            builder.BuildPartC();
        }
    }

    public abstract class Builder
    {
        public abstract void BuildPartA();
		
        public abstract void BuildPartB();
		
        public abstract void BuildPartC();
		
        public abstract Product GetProduct();
    }

    public class Product
    {
        List<object> parts = new List<object>();
		
        public void Add(string part)
        {
            parts.Add(part);
        }
		
        public string ListParts()
        {
            string str = string.Empty;

            for (int i = 0; i < parts.Count; i++)
            {
                str += parts[i] + ", ";
            }

            str = str.Remove(str.Length - 2); // removing last ",c"

            return "Product parts: " + str + "\n";
        }
    }

    public class ConcreteBuilder : Builder
    {
        Product product = new Product();
		
        public override void BuildPartA()
        {
            product.Add("PartA1");
        }
		
        public override void BuildPartB()
        {
            product.Add("PartB1");
        }
		
        public override void BuildPartC()
        {
            product.Add("PartC1");
        }
		
        public override Product GetProduct()
        {
            Product result = product;

            this.Reset();

            return result;
        }
		
        public void Reset()
        {
            product = new Product();
        }
    }
}

Output.txt: Output

Standart basic product:
Product parts: PartA1

Standart full featured product:
Product parts: PartA1, PartB1, PartC1

Custom product:
Product parts: PartA1, PartC1