The Builder pattern is a creational design pattern that separates the construction of a complex object from its representation, allowing the same construction process to create different representations.
When to Use:
- When the algorithm for creating a complex object should be independent of the object's components and how they are assembled.
- When the construction process must allow for different representations of the object being constructed.
Code Implementation:
1. The Complex Object Class
/// <summary>
/// Represents the final complex object composed of multiple components
/// </summary>
class ComplexObject
{
private List<string> components = new List<string>();
/// <summary>
/// Adds a component to the object
/// </summary>
public void AttachComponent(string component)
{
components.Add(component);
}
public void Display()
{
Console.WriteLine("\n Complex Object Created ----");
foreach(string component in components)
{
Console.WriteLine(component);
}
}
}
2. Abstract Assembler Class
/// <summary>
/// Abstract assembler that defines the steps to construct the object
/// and a method to retrieve the final product
/// </summary>
abstract class Assembler
{
public abstract void AssembleComponentA();
public abstract void AssembleComponentB();
public abstract ComplexObject GetFinalObject();
}
3. Concrete Assembler Classes
/// <summary>
/// Standard implementation of the assembler
/// </summary>
class StandardAssembler : Assembler
{
private ComplexObject product = new ComplexObject();
public override void AssembleComponentA()
{
product.AttachComponent("Standard Component A");
}
public override void AssembleComponentB()
{
product.AttachComponent("Standard Component B");
}
public override ComplexObject GetFinalObject()
{
return product;
}
}
/// <summary>
/// Premium implementation of the assembler with different components
/// </summary>
class PremiumAssembler : Assembler
{
private ComplexObject product = new ComplexObject();
public override void AssembleComponentA()
{
product.AttachComponent("Premium Component X");
}
public override void AssembleComponentB()
{
product.AttachComponent("Premium Component Y");
}
public override ComplexObject GetFinalObject()
{
return product;
}
}
4. The Orchestrator Class
/// <summary>
/// Orchestrator that manages the assembly process without knowing
/// the specific implementation details
/// </summary>
class Orchestrator
{
public void ExecuteAssembly(Assembler assembler)
{
assembler.AssembleComponentA();
assembler.AssembleComponentB();
}
}
5. Client Code
/// <summary>
/// Demonstrates the Builder pattern implementation
/// </summary>
static void DemonstrateBuilderPattern()
{
// Create the orchestrator
Orchestrator manager = new Orchestrator();
// Initialize assemblers
Assembler standardAssembler = new StandardAssembler();
Assembler premiumAssembler = new PremiumAssembler();
// Build standard product
manager.ExecuteAssembly(standardAssembler);
ComplexObject standardProduct = standardAssembler.GetFinalObject();
standardProduct.Display();
// Build premium product
manager.ExecuteAssembly(premiumAssembler);
ComplexObject premiumProduct = premiumAssembler.GetFinalObject();
premiumProduct.Display();
Console.Read();
}
Summary:
The Builder pattern is particualrly useful when constructing complex objects that require multiple steps or configurations. By separating the construction logic from the actual implementation, you can create flexible systems where different builders can produce variations of the same object type. However, for simple objects with straightforward construction, the pattern might introduce unnecessary complexity.