The builder pattern describe a way to separate an object from it's construction.
The same construction method can create different representation of the object.
Use the pattern in the following situations:
- You need to construct a complex object which has different
representation.
- The algorithm for creating the object should be independent of
the way the object's parts is assembled.
For a UML diagram of the pattern go to dofactory site.
C# Example
Lets look at a builder example:
#region Director
/// <summary>
/// The contractor is responsible for the
/// house build.
/// </summary>
class Contractor
{
#region Methods
/// <summary>
/// Construct a new house with the given
/// house builder
/// </summary>
/// <param name="house"></param>
public void Construct(HouseBuilder houseBuilder)
{
houseBuilder.BuildFloor();
houseBuilder.BuildWalls();
houseBuilder.BuildDoors();
houseBuilder.BuildWindows();
}
#endregion
}
#endregion
#region Builder
abstract class HouseBuilder
{
#region Members
protected House _house;
#endregion
#region Properties
public House House
{
get
{
return _house;
}
}
#endregion
#region Build Methods
public abstract void BuildDoors();
public abstract void BuildWindows();
public abstract void BuildWalls();
public abstract void BuildFloor();
#endregion
}
#endregion
#region Builder Product
class HousePart
{
#region Members
private string _strPartName;
#endregion
#region Properties
/// <summary>
/// The part name
/// </summary>
public string PartName
{
get
{
return _strPartName;
}
}
#endregion
#region Ctor
/// <summary>
/// Construct a new house part with the given
/// name.
/// </summary>
/// <param name="name">The given name</param>
public HousePart(string name)
{
_strPartName = name;
}
#endregion
}
class House
{
#region Members
private string _material;
private List<HousePart> _houseParts;
#endregion
#region Property
/// <summary>
/// The building material
/// </summary>
public string Material
{
get
{
return _material;
}
}
#endregion
#region Ctor
/// <summary>
/// Construct a new house with the given
/// material
/// </summary>
/// <param name="material">The given material</param>
public House(string material)
{
_material = material;
_houseParts = new List<HousePart>();
}
#endregion
#region Methods
/// <summary>
/// Adds a part of the house to the house
/// </summary>
/// <param name="part">The part to add</param>
public void AddPart(HousePart part)
{
_houseParts.Add(part);
}
#endregion
}
#endregion
#region Builder Concretes
class GlassHouseBuilder : HouseBuilder
{
#region Methods
public override void BuildFloor()
{
_house = new House("glass");
House.AddPart(new HousePart("stone floor"));
}
public override void BuildWalls()
{
House.AddPart(new HousePart(House.Material +
" walls"));
}
public override void BuildDoors()
{
House.AddPart(new HousePart("wood doors"));
}
public override void BuildWindows()
{
House.AddPart(new HousePart(House.Material +
" windows"));
}
#endregion
}
class WoodHouseBuilder : HouseBuilder
{
#region Methods
public override void BuildFloor()
{
_house = new House("wood");
House.AddPart(new HousePart(House.Material +
" floor"));
}
public override void BuildWalls()
{
House.AddPart(new HousePart(House.Material +
" floor"));
}
public override void BuildDoors()
{
House.AddPart(new HousePart("iron doors"));
}
public override void BuildWindows()
{
House.AddPart(new HousePart("glass floor"));
}
#endregion
}
#endregion
The example is easy to understand. When have a house contractor that is
responsible to build the house in the right order. We have a builder
abstract class that defines the interface for the concrete builders.
Each concrete responsible to implement the abstract methods and
therefore build the parts differently.
Summary
To sum up, the builder pattern isn't commonly used.
It resemble the abstract factory in some ways but the difference between
the two patterns is that builder is concerned with how the object is built by
different concretes and abstract factory is concerned about what products
are built. As you could see in the example there is a director that organize
the building parts therefore making the algorithm of construction abstract.