The Builder design pattern separates the construction of a complex object from its representation so that the same construction process can create different representations.
C# code examples of the Builder design pattern is provided in 3 forms:
A visualization of the classes and objects participating in this pattern.
The classes and objects participating in this pattern include:
VehicleBuilder
)
MotorCycleBuilder, CarBuilder, ScooterBuilder
)
Shop
)
Vehicle
)
This structural code demonstrates demonstrates the Builder pattern in which complex objects are created in a step-by-step fashion. The construction process can create different object representations and provides a high level of control over the assembly of the objects.
using System;
using System.Collections.Generic;
namespace DoFactory.GangOfFour.Builder.Structural
{
/// <summary>
/// MainApp startup class for Structural
/// Builder Design Pattern.
/// </summary>
public class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
public static void Main()
{
// Create director and builders
Director director = new Director();
Builder b1 = new ConcreteBuilder1();
Builder b2 = new ConcreteBuilder2();
// Construct two products
director.Construct(b1);
Product p1 = b1.GetResult();
p1.Show();
director.Construct(b2);
Product p2 = b2.GetResult();
p2.Show();
// Wait for user
Console.ReadKey();
}
}
/// <summary>
/// The 'Director' class
/// </summary>
class Director
{
// Builder uses a complex series of steps
public void Construct(Builder builder)
{
builder.BuildPartA();
builder.BuildPartB();
}
}
/// <summary>
/// The 'Builder' abstract class
/// </summary>
abstract class Builder
{
public abstract void BuildPartA();
public abstract void BuildPartB();
public abstract Product GetResult();
}
/// <summary>
/// The 'ConcreteBuilder1' class
/// </summary>
class ConcreteBuilder1 : Builder
{
private Product _product = new Product();
public override void BuildPartA()
{
_product.Add("PartA");
}
public override void BuildPartB()
{
_product.Add("PartB");
}
public override Product GetResult()
{
return _product;
}
}
/// <summary>
/// The 'ConcreteBuilder2' class
/// </summary>
class ConcreteBuilder2 : Builder
{
private Product _product = new Product();
public override void BuildPartA()
{
_product.Add("PartX");
}
public override void BuildPartB()
{
_product.Add("PartY");
}
public override Product GetResult()
{
return _product;
}
}
/// <summary>
/// The 'Product' class
/// </summary>
class Product
{
private List<string> _parts = new List<string>();
public void Add(string part)
{
_parts.Add(part);
}
public void Show()
{
Console.WriteLine("\nProduct Parts -------");
foreach (string part in _parts)
Console.WriteLine(part);
}
}
}
This real-world code demonstrates the Builder pattern in which different vehicles are assembled in a step-by-step fashion. The Shop uses VehicleBuilders to construct a variety of Vehicles in a series of sequential steps.
using System;
using System.Collections.Generic;
namespace DoFactory.GangOfFour.Builder.RealWorld
{
/// <summary>
/// MainApp startup class for Real-World
/// Builder Design Pattern.
/// </summary>
public class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
public static void Main()
{
VehicleBuilder builder;
// Create shop with vehicle builders
Shop shop = new Shop();
// Construct and display vehicles
builder = new ScooterBuilder();
shop.Construct(builder);
builder.Vehicle.Show();
builder = new CarBuilder();
shop.Construct(builder);
builder.Vehicle.Show();
builder = new MotorCycleBuilder();
shop.Construct(builder);
builder.Vehicle.Show();
// Wait for user
Console.ReadKey();
}
}
/// <summary>
/// The 'Director' class
/// </summary>
class Shop
{
// Builder uses a complex series of steps
public void Construct(VehicleBuilder vehicleBuilder)
{
vehicleBuilder.BuildFrame();
vehicleBuilder.BuildEngine();
vehicleBuilder.BuildWheels();
vehicleBuilder.BuildDoors();
}
}
/// <summary>
/// The 'Builder' abstract class
/// </summary>
abstract class VehicleBuilder
{
protected Vehicle vehicle;
// Gets vehicle instance
public Vehicle Vehicle
{
get { return vehicle; }
}
// Abstract build methods
public abstract void BuildFrame();
public abstract void BuildEngine();
public abstract void BuildWheels();
public abstract void BuildDoors();
}
/// <summary>
/// The 'ConcreteBuilder1' class
/// </summary>
class MotorCycleBuilder : VehicleBuilder
{
public MotorCycleBuilder()
{
vehicle = new Vehicle("MotorCycle");
}
public override void BuildFrame()
{
vehicle["frame"] = "MotorCycle Frame";
}
public override void BuildEngine()
{
vehicle["engine"] = "500 cc";
}
public override void BuildWheels()
{
vehicle["wheels"] = "2";
}
public override void BuildDoors()
{
vehicle["doors"] = "0";
}
}
/// <summary>
/// The 'ConcreteBuilder2' class
/// </summary>
class CarBuilder : VehicleBuilder
{
public CarBuilder()
{
vehicle = new Vehicle("Car");
}
public override void BuildFrame()
{
vehicle["frame"] = "Car Frame";
}
public override void BuildEngine()
{
vehicle["engine"] = "2500 cc";
}
public override void BuildWheels()
{
vehicle["wheels"] = "4";
}
public override void BuildDoors()
{
vehicle["doors"] = "4";
}
}
/// <summary>
/// The 'ConcreteBuilder3' class
/// </summary>
class ScooterBuilder : VehicleBuilder
{
public ScooterBuilder()
{
vehicle = new Vehicle("Scooter");
}
public override void BuildFrame()
{
vehicle["frame"] = "Scooter Frame";
}
public override void BuildEngine()
{
vehicle["engine"] = "50 cc";
}
public override void BuildWheels()
{
vehicle["wheels"] = "2";
}
public override void BuildDoors()
{
vehicle["doors"] = "0";
}
}
/// <summary>
/// The 'Product' class
/// </summary>
class Vehicle
{
private string _vehicleType;
private Dictionary<string, string> _parts =
new Dictionary<string, string>();
// Constructor
public Vehicle(string vehicleType)
{
this._vehicleType = vehicleType;
}
// Indexer
public string this[string key]
{
get { return _parts[key]; }
set { _parts[key] = value; }
}
public void Show()
{
Console.WriteLine("\n---------------------------");
Console.WriteLine("Vehicle Type: {0}", _vehicleType);
Console.WriteLine(" Frame : {0}", _parts["frame"]);
Console.WriteLine(" Engine : {0}", _parts["engine"]);
Console.WriteLine(" #Wheels: {0}", _parts["wheels"]);
Console.WriteLine(" #Doors : {0}", _parts["doors"]);
}
}
}
The .NET optimized code demonstrates the same code as above but uses
more modern C# and .NET features.
Here is an elegant C# Builder solution.
namespace Builder.NetOptimized;
using static System.Console;
/// <summary>
/// Builder Design Pattern
/// </summary>
public class Program
{
public static void Main()
{
// Create shop
var shop = new Shop();
// Construct and display vehicles
shop.Construct(new ScooterBuilder());
shop.ShowVehicle();
shop.Construct(new CarBuilder());
shop.ShowVehicle();
shop.Construct(new MotorCycleBuilder());
shop.ShowVehicle();
// Wait for user
ReadKey();
}
}
/// <summary>
/// The 'Director' class
/// </summary>
public class Shop
{
private VehicleBuilder? builder;
// Builder uses a complex series of steps
public void Construct(VehicleBuilder vehicleBuilder)
{
builder = vehicleBuilder;
builder.BuildFrame();
builder.BuildEngine();
builder.BuildWheels();
builder.BuildDoors();
}
public void ShowVehicle()
{
builder?.Vehicle.Show();
}
}
/// <summary>
/// The 'Builder' abstract class
/// </summary>
public abstract class VehicleBuilder(VehicleType vehicleType)
{
public Vehicle Vehicle { get; private set; } = new Vehicle(vehicleType);
public abstract void BuildFrame();
public abstract void BuildEngine();
public abstract void BuildWheels();
public abstract void BuildDoors();
}
/// <summary>
/// The 'ConcreteBuilder1' class
/// </summary>
public class MotorCycleBuilder : VehicleBuilder
{
// Invoke base class constructor
public MotorCycleBuilder() : base(VehicleType.MotorCycle)
{
}
public override void BuildFrame() => Vehicle[PartType.Frame] = "MotorCycle Frame";
public override void BuildEngine() => Vehicle[PartType.Engine] = "500 cc";
public override void BuildWheels() => Vehicle[PartType.Wheel] = "2";
public override void BuildDoors() => Vehicle[PartType.Door] = "0";
}
/// <summary>
/// The 'ConcreteBuilder2' class
/// </summary>
public class CarBuilder : VehicleBuilder
{
// Invoke base class constructor
public CarBuilder() : base(VehicleType.Car)
{
}
public override void BuildFrame() => Vehicle[PartType.Frame] = "Car Frame";
public override void BuildEngine() => Vehicle[PartType.Engine] = "2500 cc";
public override void BuildWheels() => Vehicle[PartType.Wheel] = "4";
public override void BuildDoors() => Vehicle[PartType.Door] = "4";
}
/// <summary>
/// The 'ConcreteBuilder3' class
/// </summary>
public class ScooterBuilder : VehicleBuilder
{
// Invoke base class constructor
public ScooterBuilder() : base(VehicleType.Scooter)
{
}
public override void BuildFrame() => Vehicle[PartType.Frame] = "Scooter Frame";
public override void BuildEngine() => Vehicle[PartType.Engine] = "50 cc";
public override void BuildWheels() => Vehicle[PartType.Wheel] = "2";
public override void BuildDoors() => Vehicle[PartType.Door] = "0";
}
/// <summary>
/// The 'Product' class
/// </summary>
public class Vehicle(VehicleType vehicleType)
{
private readonly Dictionary<PartType, string> parts = [];
private readonly VehicleType vehicleType = vehicleType;
public string this[PartType key]
{
get => parts[key];
set => parts[key] = value;
}
public void Show()
{
WriteLine("\n---------------------------");
WriteLine($"Vehicle Type: {vehicleType}");
WriteLine($" Frame : {this[PartType.Frame]}");
WriteLine($" Engine : {this[PartType.Engine]}");
WriteLine($" #Wheels: {this[PartType.Wheel]}");
WriteLine($" #Doors : {this[PartType.Door]}");
}
}
/// <summary>
/// Part type enumeration
/// </summary>
public enum PartType
{
Frame,
Engine,
Wheel,
Door
}
/// <summary>
/// Vehicle type enumeration
/// </summary>
public enum VehicleType
{
Car,
Scooter,
MotorCycle
}