Introduction
In this article, we will learn about Builder Design Pattern and create a demo application to understand it practically. We will explore how Builder pattern helps us in creation of complex objects.
Outlines
- What is Builder Pattern
- When to use Builder Pattern
- Understand Definition with Example
- Problem with Builder Pattern
What is Builder Pattern
Builder Design Pattern is described in Gang of Four (GoF) book and comes in the category of Creational Pattern. Following is the definition of Builder Pattern as taken from Gang of Four (GoF) book:
“Separate the construction of a complex object from its representation so that the same construction process can create different representations.”
We will understand this definition in detail under "Understand Definition with Example" section of this article.
When to use Builder Pattern
This pattern can be used where we need to do a lot of work to build similar kind of complex objects in step by step fashion. In another way we can say that this pattern is useful where we need to create a complex object by assembling small objects (which are parts of a complex object) using a certain procedure or algorithm.
In many scenarios we have to create several kind of complex objects but those all objects follow similar procedure of construction. For example, basic steps to build different kind of Bicycles (Kids Bicycles, Standard Bicycles, Ladies Bicycles and Mountain Bicycles etc.) are same. We got two things here:
- Common steps to build a complex objects (will see how it goes to a Director)
- Different representation of that complex object and create its parts accordingly (will see how it goes to Concrete Builders)
Understand Definition with Example
So let’s take same scenario to understand Builder pattern in detail. Suppose we want to make few Bicycle objects which are quite complex objects. To make Bicycle, we need other small objects which would be parts of bicycle like bicycle frame, wheels, handle, gear, chain etc. In order to construct Bicycle now we need to assemble all parts in step by step fashion only then Bicycle can be constructed. In this section we will implement Builder Pattern to create different kind of bicycles by assembling required parts appropriate for those bicycles.
Let’s understand the definition of Builder Pattern with the help of above mentioned scenario. First create a design diagram of above mentioned scenario and try to associate the definition with the scenario.
Following diagram shows required entities or classes to implement the above mentioned scenario by using Builder Pattern:
So further we will follow above design and explain the standard definition of Builder Pattern:
According to definition "Separate the construction of a complex object from its representation …” so in the above diagram BicycleBuildDirector class will have all construction logic to create complex object which will be representation of actual builder class namely Bicycle. “.. so that the same construction process can create different representations.” Here same BicycleBuildDirector can be used to create different representation of Bicycle namely KidsBicycleBuilder and RoadBicycleBuilder.
Main Component/Participants of Builder Pattern
- Director (BicycleBuildDirector)
- Abstract Builder (IBicycleBuilder)
- Concrete Builder (KidsBicycleBuilder, RoadBicycleBuilder etc.)
- Product (Bicycle)
Following is the implementation of above mentioned scenario:
Create a class which represents the product object.
public class Bicycle
{
public string BicycleType { get; set; }
public int BicycleHeight { get; set; }
public string BicycleColour { get; set; }
}
Now create an interface called IBicycleBuilder, this interface will have all methods definition which are required to create the bicycle.
public interface IBicycleBuilder
{
void SetHeight(int height);
void SetFrame();
void SetGears();
void PutTires();
void SetColour(string colour);
void PutAccessaries();
Bicycle GetBicycle();
}
Now we want to create bicycle for kids. So lets create a class called KidsBicycleBuilder. This class will implement IBicycleBuilder interface, implementation will be according to the requirements for Kids bicycle.
class KidsBicycleBuilder : IBicycleBuilder
{
private Bicycle bicycle;
public KidsBicycleBuilder()
{
bicycle = new Bicycle();
bicycle.BicycleType = "Kids Bicycle";
}
public void SetHeight(int height)
{
Console.WriteLine("Bicycle is set with given height: {0}", height);
bicycle.BicycleHeight = height;
}
public void SetFrame()
{
Console.WriteLine("Frame has been set.");
}
public void SetGears()
{
Console.WriteLine("Gears have been set.");
}
public void PutTires()
{
Console.WriteLine("Tires have been set.");
}
public void SetColour(string colour)
{
Console.WriteLine("Bicycle is set with given colour: {0}", colour);
bicycle.BicycleColour = colour;
}
public void PutAccessaries()
{
Console.WriteLine("Accessaries have been set.");
}
public Bicycle GetBicycle()
{
return this.bicycle;
}
}
In similar way create more class called RoadBicycleBuilder and implement IBicycleBuilder interface. This class will build a Road Bicycle (for complete code, please download source code given along with this article).
class RoadBicycleBuilder : IBicycleBuilder {...}
Let's create Director called BicycleBuildDirector which contains flow or algorithm to construct Bicycle using a bicycle builder. Director calls method of builder class in a order as needed in creation process of bicycle.
public class BicycleBuildDirector
{
SellDepartment sellDepartment = new SellDepartment();
public Bicycle Construct(IBicycleBuilder builder, string colour, int height)
{
Console.WriteLine("We have sarted process for Bicycle manufacturing");
builder.SetFrame();
builder.SetGears();
builder.SetColour(colour);
builder.SetHeight(height);
builder.PutTires();
builder.PutAccessaries();
Bicycle bicycle = builder.GetBicycle();
sellDepartment.GenerateInvoice(bicycle.BicycleType, colour, height);
Console.WriteLine("{0} is ready for your disposal.\n ** Happy Riding ! **", bicycle.GetType());
return bicycle;
}
}
Following code shows how client can create instance of BicycleBuildDirector class and calls Construct method by passing required parameter to get desired bicycle.
static void Main(string[] args)
{
BicycleBuildDirector buildDirector = new BicycleBuildDirector();
Bicycle bicycle = buildDirector.Construct(new KidsBicycleBuilder(), "Red", 16);
}
if client want to get a road bicycle then he just need to modify arguments of Construct method of the BicycleBuildDirector as given below:
Bicycle bicycle = buildDirector.Construct(new RoadBicycleBuilder(), "Blue", 24);
In this way, by using different builders with same director, client is able to create different types of bicycles.
Problem with Builder Pattern
Every design pattern belongs to certain problem domain. As we already learned that Builder pattern should be used while we need to create similar kind of objects which follow step by step process of creation. So until we got such situation, using Builder pattern will be an overhead.
Further there are some discussion on disadvantage of Builder pattern i.e. at this stackoverflow page. It is said that using Builder Pattern, we need to create more classes (which introduce more complexity). These all are because of trying to use Builder Pattern in relatively simple scenarios or where it is not needed appropriately.
But while we use it in enough complex situations, it help us to put the overall creation process in better way and enhance readability and maintainability and thus help us deal with complexity with ease.
Conclusion
In this article, we had a walkthrough to learn Builder Pattern and its use. We understood the context of Builder Pattern and how to use it to enhance maintainability of application. Thanks for reading. Your comments and suggestions for improvement are most welcome.
References