Builder¶
- Builder
- UML class diagram
- Participants
- Structural code in C# .{10} - Output
- Real-world code in C# .{10}
- .NET Optimized code in C# .{10}
Summary: Separate the construction of a complex object from its representation so that the same construction process can create different representations.
Frequency of use: Medium low
UML class diagram¶
Participants¶
The classes and objects participating in this pattern are:
Builder (VehicleBuilder
)
- specifies an abstract interface for creating parts of a Product object
ConcreteBuilder (MotorCycleBuilder, CarBuilder, ScooterBuilder
)
- constructs and assembles parts of the product by implementing the Builder interface
- defines and keeps track of the representation it creates
- provides an interface for retrieving the product
Director (Shop
)
- constructs an object using the Builder interface
Product (Vehicle
)
- represents the complex object under construction. ConcreteBuilder builds the product's internal representation and defines the process by which it's assembled
- includes classes that define the constituent parts, including interfaces for assembling the parts into the final result
Structural code in C# .{10}¶
This structural code 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);
}
}
}
Output¶
Real-world code in C# .{10}¶
This real-world code demonstates 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"]);
}
}
}
---------------------------
Vehicle Type: Scooter
Frame : Scooter Frame
Engine : none
#Wheels: 2
#Doors : 0
---------------------------
Vehicle Type: Car
Frame : Car Frame
Engine : 2500 cc
#Wheels: 4
#Doors : 4
---------------------------
Vehicle Type: MotorCycle
Frame : MotorCycle Frame
Engine : 500 cc
#Wheels: 2
#Doors : 0
.NET Optimized code in C# .{10}¶
using System;
using System.Collections.Generic;
namespace DoFactory.GangOfFour.Builder.NETOptimized
{
/// <summary>
/// MainApp startup class for .NET optimized
/// Builder Design Pattern.
/// </summary>
public class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
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
Console.ReadKey();
}
}
/// <summary>
/// The 'Director' class
/// </summary>
class Shop
{
private VehicleBuilder _vehicleBuilder;
// Builder uses a complex series of steps
public void Construct(VehicleBuilder vehicleBuilder)
{
_vehicleBuilder = vehicleBuilder;
_vehicleBuilder.BuildFrame();
_vehicleBuilder.BuildEngine();
_vehicleBuilder.BuildWheels();
_vehicleBuilder.BuildDoors();
}
public void ShowVehicle()
{
_vehicleBuilder.Vehicle.Show();
}
}
/// <summary>
/// The 'Builder' abstract class
/// </summary>
abstract class VehicleBuilder
{
public Vehicle Vehicle { get; private set; }
// Constructor
public VehicleBuilder(VehicleType vehicleType)
{
Vehicle = new Vehicle(vehicleType);
}
public abstract void BuildFrame();
public abstract void BuildEngine();
public abstract void BuildWheels();
public abstract void BuildDoors();
}
/// <summary>
/// The 'ConcreteBuilder1' class
/// </summary>
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>
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>
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>
class Vehicle
{
private VehicleType _vehicleType;
private Dictionary<PartType, string> _parts = new Dictionary<PartType, string>();
// Constructor
public Vehicle(VehicleType vehicleType)
{
_vehicleType = vehicleType;
}
public string this[PartType 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}",
this[PartType.Frame]);
Console.WriteLine(" Engine : {0}",
this[PartType.Engine]);
Console.WriteLine(" #Wheels: {0}",
this[PartType.Wheel]);
Console.WriteLine(" #Doors : {0}",
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
}
}