- Builder pattern isolates a view from its logic.
- It separates the construction of a complex object (Process) from its representation (Data).
- Therefore, the same construction process can create classes with different data.
- This pattern is concerned with how a single object is made up by the different factories.
- The client can still direct the steps taken by the Builder, without knowing how the actual work is accomplished.
- Builders frequently encapsulate the construction of "Composite" objects because the procedures involved are often repetitive and complex.
- A scenario where the Builder can be helpful is when building a code generator.
- Say you’re writing an application that generates stored procedures for different target databases (SQL Server, Oracle, Db2).
- The actual output is quite different but the different steps of creating the separate procedures that implement the CRUD statements are similar.
- Factory patterns create objects in one single step, while Builder gives you more control in that each step in the construction process can be customized
Participants
Product
(Vehicle)
- Represents the complex object under construction.
- Each implementation of the
ConcreteBuilder
builds the product's internal representation and defines the process by which it's assembled.
Builder
(IVehicleBuilder)
- Specifies an abstract interface for creating parts of a
Product
object.
- This interfaces defines how to a
ConcreteBuilder
instance represents itself.
ConcreteBuilder
(CarBuilder, MotorCycleBuilder)
- 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
(VehicleMaker)
- Constructs an object using the
Builder
interface.
var vehicleMaker1 = new VehicleMaker(new MotorCycleBuilder());
vehicleMaker1.BuildVehicle();
var vehicle1 = vehicleMaker1.GetVehicle();
Console.WriteLine(vehicle1.GetFeatures());
var vehicleMaker2 = new VehicleMaker(new CarBuilder());
vehicleMaker2.BuildVehicle();
var vehicle2 = vehicleMaker2.GetVehicle();
Console.WriteLine(vehicle2.GetFeatures());
public interface IVehicle
{
string VehicleType { get; set; }
string this[string key] { get; set; }
string GetFeatures();
}
public class Vehicle : IVehicle
{
public string VehicleType { get; set; }
private readonly Dictionary<string, string> _parts = new Dictionary<string, string>();
public string this[string key]
{
get => _parts[key];
set => _parts[key] = value;
}
public string GetFeatures() => string.Join('\\n', _parts.Select(x => $"{x.Key}: {x.Value}"));
}
public interface IVehicleBuilder
{
void Construct();
IVehicle GetVehicle();
}
public class MotorCycleBuilder : IVehicleBuilder
{
private IVehicle _vehicle;
public void Construct()
{
_vehicle = new Vehicle
{
VehicleType = "MotorCycle",
["frame"] = "MotorCycle Frame",
["engine"] = "500 cc",
["wheels"] = "2",
["doors"] = "0"
};
}
public IVehicle GetVehicle() => _vehicle;
}
public class CarBuilder : IVehicleBuilder
{
private IVehicle _vehicle;
public void Construct()
{
_vehicle = new Vehicle
{
VehicleType = "Car",
["frame"] = "Car Frame",
["engine"] = "2500 cc",
["wheels"] = "4",
["doors"] = "4"
};
}
public IVehicle GetVehicle() => _vehicle;
}
public class VehicleMaker
{
private IVehicleBuilder _builder;
public VehicleMaker(IVehicleBuilder builder) => _builder = builder;
public void BuildVehicle() => _builder.Construct();
public IVehicle GetVehicle() => _builder.GetVehicle();
}
Rules of Thumb
- Sometimes creational patterns are complementary: Builder can use one of the other patterns to implement which components get built.
- Abstract Factory, Builder, and Prototype can use Singleton in their implementations.
- Builder focuses on constructing a complex object step by step.
- Abstract Factory emphasizes a family of product objects (either simple or complex).
- Builder returns the product as a final step, but as far as the Abstract Factory is concerned, the product gets returned immediately.
- Builder often builds a Composite.
C# Design Patterns - Faceted Builder - Code Maze