Object oriented Design patterns : Builder Patterns


Summary:  Separate the construction of a complex object from its representation so that the same construction process can create different representations.



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#

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.

  1. using System;

  2. using System.Collections.Generic;

  3.  

  4. namespace DoFactory.GangOfFour.Builder.Structural

  5. {

  6.   /// <summary>

  7.   /// MainApp startup class for Structural

  8.   /// Builder Design Pattern.

  9.   /// </summary>

  10.   public class MainApp

  11.   {

  12.     /// <summary>

  13.     /// Entry point into console application.

  14.     /// </summary>

  15.     public static void Main()

  16.     {

  17.       // Create director and builders

  18.       Director director = new Director();

  19.  

  20.       Builder b1 = new ConcreteBuilder1();

  21.       Builder b2 = new ConcreteBuilder2();

  22.  

  23.       // Construct two products

  24.       director.Construct(b1);

  25.       Product p1 = b1.GetResult();

  26.       p1.Show();

  27.  

  28.       director.Construct(b2);

  29.       Product p2 = b2.GetResult();

  30.       p2.Show();

  31.  

  32.       // Wait for user

  33.       Console.ReadKey();

  34.     }

  35.   }

  36.  

  37.   /// <summary>

  38.   /// The 'Director' class

  39.   /// </summary>

  40.   class Director

  41.   {

  42.     // Builder uses a complex series of steps

  43.     public void Construct(Builder builder)

  44.     {

  45.       builder.BuildPartA();

  46.       builder.BuildPartB();

  47.     }

  48.   }

  49.  

  50.   /// <summary>

  51.   /// The 'Builder' abstract class

  52.   /// </summary>

  53.   abstract class Builder

  54.   {

  55.     public abstract void BuildPartA();

  56.     public abstract void BuildPartB();

  57.     public abstract Product GetResult();

  58.   }

  59.  

  60.   /// <summary>

  61.   /// The 'ConcreteBuilder1' class

  62.   /// </summary>

  63.   class ConcreteBuilder1 : Builder

  64.   {

  65.     private Product _product = new Product();

  66.  

  67.     public override void BuildPartA()

  68.     {

  69.       _product.Add("PartA");

  70.     }

  71.  

  72.     public override void BuildPartB()

  73.     {

  74.       _product.Add("PartB");

  75.     }

  76.  

  77.     public override Product GetResult()

  78.     {

  79.       return _product;

  80.     }

  81.   }

  82.  

  83.   /// <summary>

  84.   /// The 'ConcreteBuilder2' class

  85.   /// </summary>

  86.   class ConcreteBuilder2 : Builder

  87.   {

  88.     private Product _product = new Product();

  89.  

  90.     public override void BuildPartA()

  91.     {

  92.       _product.Add("PartX");

  93.     }

  94.  

  95.     public override void BuildPartB()

  96.     {

  97.       _product.Add("PartY");

  98.     }

  99.  

  100.     public override Product GetResult()

  101.     {

  102.       return _product;

  103.     }

  104.   }

  105.  

  106.   /// <summary>

  107.   /// The 'Product' class

  108.   /// </summary>

  109.   class Product

  110.   {

  111.     private List<string> _parts = new List<string>();

  112.  

  113.     public void Add(string part)

  114.     {

  115.       _parts.Add(part);

  116.     }

  117.  

  118.     public void Show()

  119.     {

  120.       Console.WriteLine("\nProduct Parts -------");

  121.       foreach (string part in _parts)

  122.         Console.WriteLine(part);

  123.     }

  124.   }

  125. }

  126.  
  127.  
Output
Product Parts -------
PartA
PartB

Product Parts -------
PartX
PartY

Real-world code in C#

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.

  1. using System;

  2. using System.Collections.Generic;

  3.  

  4. namespace DoFactory.GangOfFour.Builder.RealWorld

  5. {

  6.   /// <summary>

  7.   /// MainApp startup class for Real-World

  8.   /// Builder Design Pattern.

  9.   /// </summary>

  10.   public class MainApp

  11.   {

  12.     /// <summary>

  13.     /// Entry point into console application.

  14.     /// </summary>

  15.     public static void Main()

  16.     {

  17.       VehicleBuilder builder;

  18.  

  19.       // Create shop with vehicle builders

  20.       Shop shop = new Shop();

  21.  

  22.       // Construct and display vehicles

  23.       builder = new ScooterBuilder();

  24.       shop.Construct(builder);

  25.       builder.Vehicle.Show();

  26.  

  27.       builder = new CarBuilder();

  28.       shop.Construct(builder);

  29.       builder.Vehicle.Show();

  30.  

  31.       builder = new MotorCycleBuilder();

  32.       shop.Construct(builder);

  33.       builder.Vehicle.Show();

  34.  

  35.       // Wait for user

  36.       Console.ReadKey();

  37.     }

  38.   }

  39.  

  40.   /// <summary>

  41.   /// The 'Director' class

  42.   /// </summary>

  43.   class Shop

  44.   {

  45.     // Builder uses a complex series of steps

  46.     public void Construct(VehicleBuilder vehicleBuilder)

  47.     {

  48.       vehicleBuilder.BuildFrame();

  49.       vehicleBuilder.BuildEngine();

  50.       vehicleBuilder.BuildWheels();

  51.       vehicleBuilder.BuildDoors();

  52.     }

  53.   }

  54.  

  55.   /// <summary>

  56.   /// The 'Builder' abstract class

  57.   /// </summary>

  58.   abstract class VehicleBuilder

  59.   {

  60.     protected Vehicle vehicle;

  61.  

  62.     // Gets vehicle instance

  63.     public Vehicle Vehicle

  64.     {

  65.       get { return vehicle; }

  66.     }

  67.  

  68.     // Abstract build methods

  69.     public abstract void BuildFrame();

  70.     public abstract void BuildEngine();

  71.     public abstract void BuildWheels();

  72.     public abstract void BuildDoors();

  73.   }

  74.  

  75.   /// <summary>

  76.   /// The 'ConcreteBuilder1' class

  77.   /// </summary>

  78.   class MotorCycleBuilder : VehicleBuilder

  79.   {

  80.     public MotorCycleBuilder()

  81.     {

  82.       vehicle = new Vehicle("MotorCycle");

  83.     }

  84.  

  85.     public override void BuildFrame()

  86.     {

  87.       vehicle["frame"] = "MotorCycle Frame";

  88.     }

  89.  

  90.     public override void BuildEngine()

  91.     {

  92.       vehicle["engine"] = "500 cc";

  93.     }

  94.  

  95.     public override void BuildWheels()

  96.     {

  97.       vehicle["wheels"] = "2";

  98.     }

  99.  

  100.     public override void BuildDoors()

  101.     {

  102.       vehicle["doors"] = "0";

  103.     }

  104.   }

  105.  

  106.  

  107.   /// <summary>

  108.   /// The 'ConcreteBuilder2' class

  109.   /// </summary>

  110.   class CarBuilder : VehicleBuilder

  111.   {

  112.     public CarBuilder()

  113.     {

  114.       vehicle = new Vehicle("Car");

  115.     }

  116.  

  117.     public override void BuildFrame()

  118.     {

  119.       vehicle["frame"] = "Car Frame";

  120.     }

  121.  

  122.     public override void BuildEngine()

  123.     {

  124.       vehicle["engine"] = "2500 cc";

  125.     }

  126.  

  127.     public override void BuildWheels()

  128.     {

  129.       vehicle["wheels"] = "4";

  130.     }

  131.  

  132.     public override void BuildDoors()

  133.     {

  134.       vehicle["doors"] = "4";

  135.     }

  136.   }

  137.  

  138.   /// <summary>

  139.   /// The 'ConcreteBuilder3' class

  140.   /// </summary>

  141.   class ScooterBuilder : VehicleBuilder

  142.   {

  143.     public ScooterBuilder()

  144.     {

  145.       vehicle = new Vehicle("Scooter");

  146.     }

  147.  

  148.     public override void BuildFrame()

  149.     {

  150.       vehicle["frame"] = "Scooter Frame";

  151.     }

  152.  

  153.     public override void BuildEngine()

  154.     {

  155.       vehicle["engine"] = "50 cc";

  156.     }

  157.  

  158.     public override void BuildWheels()

  159.     {

  160.       vehicle["wheels"] = "2";

  161.     }

  162.  

  163.     public override void BuildDoors()

  164.     {

  165.       vehicle["doors"] = "0";

  166.     }

  167.   }

  168.  

  169.   /// <summary>

  170.   /// The 'Product' class

  171.   /// </summary>

  172.   class Vehicle

  173.   {

  174.     private string _vehicleType;

  175.     private Dictionary<string,string> _parts =

  176.       new Dictionary<string,string>();

  177.  

  178.     // Constructor

  179.     public Vehicle(string vehicleType)

  180.     {

  181.       this._vehicleType = vehicleType;

  182.     }

  183.  

  184.     // Indexer

  185.     public string this[string key]

  186.     {

  187.       get { return _parts[key]; }

  188.       set { _parts[key] = value; }

  189.     }

  190.  

  191.     public void Show()

  192.     {

  193.       Console.WriteLine("\n---------------------------");

  194.       Console.WriteLine("Vehicle Type: {0}", _vehicleType);

  195.       Console.WriteLine(" Frame : {0}", _parts["frame"]);

  196.       Console.WriteLine(" Engine : {0}", _parts["engine"]);

  197.       Console.WriteLine(" #Wheels: {0}", _parts["wheels"]);

  198.       Console.WriteLine(" #Doors : {0}", _parts["doors"]);

  199.     }

  200.   }

  201. }

  202.  

  203.  
Output
---------------------------
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