Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Builder Design Pattern

DZone's Guide to

Builder Design Pattern

·
Free Resource

Builder Design Pattern

The builder pattern is a design pattern that allows for the step-by-step creation of complex objects using the correct sequence of actions. The construction is controlled by a director object that only needs to know the type of object it is to create.

What is the Builder Pattern?

The builder pattern is a Gang of Four design pattern. This is a creational pattern as it is to control class instantiation. The builder pattern is used to create complex objects with constituent parts that must be created in the same order or using a specific algorithm. An external class, known as the director, controls the construction algorithm.

An example of this pattern could exist in a fast food restaurant system. It may be that each time a standard meal is prepared, it can include one burger or sandwich, one side order, a drink and a special offer item. The employee taking the order selects the type of meal and the builder pattern is used to determine exactly what goes into each meal.

Using this model, when the employee selects a "Jolly Vegetarian", the ordering system determines that the meal will include a vegeburger, an order of fries, some orange juice and a voucher for a free donut. If the customer orders a "Mischievous Mexican", they receive a spicy burger, a side order of nachos, a shot of tequila and a free hat. In each case, the constituent parts are the same and are created in the same order. The final meal is, of course, quite different.

Implementing the Builder Pattern

Builder Design Pattern UML Diagram

The UML class diagram above describes an implementation of the builder design pattern. The classes in the diagram are described below:

  • Product. The product class defines the type of the complex object that is to be generated by the builder pattern.
  • Builder. This abstract base class defines all of the steps that must be taken in order to correctly create a product. Each step is generally abstract as the actual functionality of the builder is carried out in the concrete subclasses. The GetProduct method is used to return the final product. The builder class is often replaced with a simple interface.
  • ConcreteBuilder. There may be any number of concrete builder classes inheriting from Builder. These classes contain the functionality to create a particular complex product.
  • Director. The director class controls the algorithm that generates the final product object. A director object is instantiated and its Construct method is called. The method includes a parameter to capture the specific concrete builder object that is to be used to generate the product. The director then calls methods of the concrete builder in the correct order to generate the product object. On completion of the process, the GetProduct method of the builder object can be used to return the product.

The following shows the basic code of the builder design pattern implemented using C#. For brevity the properties of the Product class are declared using C# 3.0 automatically implemented property syntax. These could be replaced with full definitions for earlier versions of the language:

public class Director
{
    public void Construct(Builder builder)
    {
        builder.BuildPart1();
        builder.BuildPart2();
        builder.BuildPart3();
    }
}


public abstract class Builder
{
    public abstract void BuildPart1();
    public abstract void BuildPart2();
    public abstract void BuildPart3();
    public abstract Product GetProduct();
}


public class ConcreteBuilder : Builder
{
    private Product _product = new Product();

    public override void BuildPart1()
    {
        _product.Part1 = "Part 1";
    }

    public override void BuildPart2()
    {
        _product.Part2 = "Part 2";
    }

    public override void BuildPart3()
    {
        _product.Part3 = "Part 3";
    }

    public override Product GetProduct()
    {
        return _product;
    }
}


public class Product
{
    public string Part1 { get; set; }
    public string Part2 { get; set; }
    public string Part3 { get; set; }
}

Example Builder

To show a real-world, but very simplistic, example of the use of a design pattern, we will create two builders that generate the fast food restaurant meals described earlier in this article. Each builder will create a meal with a named burger, side order, drink, special offer item and a price. In a real application, this process would probably be more complex and may require that the items be created in the correct order so that the price could be correctly calculated. The individual elements of the meal may also be complex objects in their own right.

public class MealDirector
{
    public void MakeMeal(MealBuilder mealBuilder)
    {
        mealBuilder.AddSandwich();
        mealBuilder.AddSideOrder();
        mealBuilder.AddDrink();
        mealBuilder.AddOfferItem();
        mealBuilder.SetPrice();
    }
}


public abstract class MealBuilder
{
    public abstract void AddSandwich();
    public abstract void AddSideOrder();
    public abstract void AddDrink();
    public abstract void AddOfferItem();
    public abstract void SetPrice();
    public abstract Meal GetMeal();
}


public class JollyVegetarianMealBuilder : MealBuilder
{
    private Meal _meal = new Meal();

    public override void AddSandwich() { _meal.Sandwich = "Vegeburger"; }
    public override void AddSideOrder() { _meal.SideOrder = "Fries"; }
    public override void AddDrink() { _meal.Drink = "Orange juice"; }
    public override void AddOfferItem() { _meal.Offer = "Donut voucher"; }
    public override void SetPrice() { _meal.Price = 4.99; }
    public override Meal GetMeal() { return _meal; }
}


public class MischievousMexicanBuilder : MealBuilder
{
    private Meal _meal = new Meal();

    public override void AddSandwich() { _meal.Sandwich = "Spicy burger"; }
    public override void AddSideOrder() { _meal.SideOrder = "Nachos"; }
    public override void AddDrink() { _meal.Drink = "Tequila"; }
    public override void AddOfferItem() { _meal.Offer = "Hat"; }
    public override void SetPrice() { _meal.Price = 5.49; }
    public override Meal GetMeal() { return _meal; }
}


public class Meal
{
    public string Sandwich { get; set; }
    public string SideOrder { get; set; }
    public string Drink { get; set; }
    public string Offer { get; set; }
    public double Price { get; set; }

    public override string ToString()
    {
        return string.Format("{0}\n{1}\n{2}\n{3}\n{4:f2}", Sandwich, SideOrder,
            Drink, Offer, Price);
    }
}

Testing the Builder

We can test the example builder code using a console application. In the following Main method, the two builders are used to create the two varieties of meal. The contents of the meals' properties are outputted to the console using the overridden ToString method.

static void Main(string[] args)
{
    MealDirector director = new MealDirector();
    MealBuilder jvmb = new JollyVegetarianMealBuilder();
    director.MakeMeal(jvmb);
    Meal vegMeal = jvmb.GetMeal();
    Console.WriteLine(vegMeal);
    Console.WriteLine();

    MealBuilder mmmb = new MischievousMexicanBuilder();
    director.MakeMeal(mmmb);
    Meal mexMeal = mmmb.GetMeal();
    Console.WriteLine(mexMeal);
}

/* OUTPUT

Vegeburger
Fries
Orange juice
Donut voucher
4.99

Spicy burger
Nachos
Tequila
Hat
5.49

*/

Republished with permission from the BlackWasp Web Site
©2006-2008 BlackWasp All Rights Reserved

Click for the original article.

Topics:

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}