ARTICLE

Object Instantiation in C# Part IV The Builder Pattern

Posted by Matthew Cochran Articles | Visual C# June 27, 2007
There are many ways to approach object instantiation. In this article we’ll cover a few of the patterns used to instantiate objects.
Reader Level:

Part III. Builders

In Part I of this two-part article, we talked about basic instantiation and different ways constructors can work.  In Part II we looked at using factory methods.  In Part III we looked at abstract factories and in this article we'll be looking at how to implement a builder.

A Builder

The difference between the abstract factory and the builder is that the abstract factory is primarily concerned with what is being built and the builder is primarily concerned with how something is being built.

In this example, we'll be building two different kinds of cars, a station wagon and a race car.  The cars are instances of the same Car class with different parts.

public abstract class Tire {}
public abstract class Engine { }
public abstract class Frame { }

public class Car
{

    private Tire[] m_tires;
    private Engine m_engine;
    private Frame m_frame;

    public Tire[] Tires
    {
        get { return m_tires; }
        internal set { m_tires = value; }
    }

    public Engine Engine
    {
        get { return m_engine; }
        internal set { m_engine = value; }
    }

    public Frame Frame
    {
        get { return m_frame; }
        internal set { m_frame = value; }
    }
}

Here are the different definitions for each type of part:

internal class RacingTire : Tire { }
internal class SixCylinderEngine : Engine { }
internal class RacingFrame : Frame { }

internal class NormalTire : Tire { }
internal class FourCylinderEngine : Engine { }
internal class StationWagonFrame : Frame { }

Next we will define an abstract factory that will build an instance of a car but instead of focusing on the type of car being built, we'll focus on the parts so instead of calling it an abstract factory, we'll call it a builder.

Here is our abstract builder contract:

public abstract class CarBuilderBase
{
    public abstract Car Build();
}

And here is our concrete builder:

public class CarBuilder : CarBuilderBase
{

    public CarBuilder(CarBuilderBase strategy)
    {
        m_strategy = strategy;
    }

    private CarBuilderBase m_strategy;

    public CarBuilderBase Strategy
    {
        get { return m_strategy; }
        set { m_strategy = value; }
    }

    public override Car Build()
    {
        return m_strategy.Build();
    }
}

Now, we'll define our two builders which will be responsible for how a car is constructed:

internal class StationWagonBuilder : CarBuilderBase
{
    public override Car Build()
    {
        Car result = new Car();
        result.Engine = new FourCylinderEngine();
        result.Frame = new StationWagonFrame();
        result.Tires = new Tire[]
        {
            new NormalTire(),
            new NormalTire(),
            new NormalTire(),
            new NormalTire()
        };

        return result;
    }
}

internal class RacingCarBuilder: CarBuilderBase
{
   public override Car Build()
    {
        Car result = new Car();
        result.Engine = new SixCylinderEngine();
        result.Frame = new RacingFrame();
        result.Tires = new Tire[]
        {
            new RacingTire(),
            new RacingTire(),
            new RacingTire(),
            new RacingTire()
        };

        return result;
    }
}

So now, in our implementing code we instantiate objects just as we do with the abstract factory pattern.

CarBuilder autoFactory = new CarBuilder(new RacingCarBuilder());
Car result = autoFactory.Build();
autoFactory.Strategy = new StationWagonBuilder();
Car stationWagon = autoFactory.Build();

As you can see, once you have a basic understanding of an abstract factory from the previous article, it is not really too much different from the builder.

In the next, and final article we'll look at a way to avoid instantiation altogether.

Until next time,
Happy coding

Login to add your contents and source code to this article
post comment
     

Hi Matt, First of all thanks for sharing all this with us :) THis is my query - Why do we need the abstract builder contract: public abstract class CarBuilderBase () when we could accomplish all of this with the concrete builder: public class CarBuilder . I mean we could have an over-ridable Build method in this class and then use this to route to appropriate vrsions of the method absed on the object being instantiated. It might be a naive question that I have but nevertheless I dont quite get this. Thanks for your help, Rakesh.

Posted by Rakesh Nair Aug 22, 2007
COMMENT USING
PREMIUM SPONSORS
Over-C is a holistic consortium of communications and technology specialists. We build, deploy and market both business as well as consumer products and solutions.
Join a Chapter
SPONSORED BY
  • PDF reports have never been easier to create. With our included WYSIWYG Designer, you can layout your reports, set up your data source and let DynamicPDF ReportWriter do the rest.
Join a Chapter