Introduction
Design patterns are very useful and help in resolving many real time issues. In this article, we will try to understand Builder Pattern with the help of a sample C# program.
Background
Builder Pattern belongs to Creational Pattern as it deals with object creation. This pattern is used multiple times in .NET Framework. One example would be ConnectionStringBuilder
. Builder Pattern comes into the picture when we need to create a product using a series of complex processes where each process can be separated. That means we can separate each step of object creation and the same object mechanism can be used for creating similiar products or objects.
GoF describes Builder Pattern as Separate the construction of a complex object from its representation so that the same construction process can create different representations. Builder Pattern consists of the below items:
Director
: Director
is responsible for creation of object using Builder
interface or base class. Builder
: Base class or Interface which has different steps mentioned for creating a Product
. ConcreteBuilder
: Defines the concrete builder which is an implementation of the above Builder
. Concrete Builder
will help us to create and get the below Product
using a series of steps mentioned in Builder
. Product
: The final Product
, which will be created through many complex steps.
Using the Code
To start with the sample program, I have created a Television
(Product
) class as below. This Product
will be constructed by the Builder
. I have added different properties to show the different parts of product.
class Television
{
public string Code { get; set; }
public string DisplayTechnology { get; set; }
public string HDFormat { get; set; }
public string ScreenType { get; set; }
public string Size { get; set; }
public string Feature { get; set; }
}
Now, we will create the TelevisionBuilder
(Builder
), which will define the complex steps for creating the Product
. We can create the Builder
as an Interface or Base Class. If you look at the below class definition, you can see the steps for creating the Product
and property or method to access the created Product
.
abstract class TelevisionBuilder
{
protected Television television;
public abstract void SetCode();
public abstract void SetDisplayTechnology();
public abstract void SetHDFormat();
public abstract void SetScreenType();
public abstract void SetSize();
public abstract void SetFeature();
public Television Television
{
get { return television; }
}
}
Defining FullHD40TVBuilder
(ConcreteBuilder1
) with respective implementation.
class FullHD40TVBuilder : TelevisionBuilder
{
public FullHD40TVBuilder()
{
television = new Television();
}
public override void SetCode()
{
television.Code = "FullHD40TV";
}
public override void SetDisplayTechnology()
{
television.DisplayTechnology = "LCD";
}
public override void SetHDFormat()
{
television.HDFormat = "FullHD";
}
public override void SetScreenType()
{
television.ScreenType="Flat";
}
public override void SetSize()
{
television.Size="40";
}
public override void SetFeature()
{
television.Feature = "1 HDMI Ports, 1 USB Ports, Remote";
}
}
Defining SMARTLED54TVBuilder
(ConcreteBuilder2
) with respective implementation.
class SMARTLED54TVBuilder : TelevisionBuilder
{
public SMARTLED54TVBuilder()
{
television = new Television();
}
public override void SetCode()
{
television.Code = "SMARTLED54TV";
}
public override void SetDisplayTechnology()
{
television.DisplayTechnology = "LED";
}
public override void SetHDFormat()
{
television.HDFormat = "FullHD";
}
public override void SetScreenType()
{
television.ScreenType="Flat";
}
public override void SetSize()
{
television.Size="54";
}
public override void SetFeature()
{
television.Feature="2 HDMI Ports, 2 USB Ports, Built in WIFI, Ethernet, Remote";
}
}
Defining Curved4K65LEDTVBuilder
(ConcreteBuilder3
) with respective implementation.
class Curved4K65LEDTVBuilder : TelevisionBuilder
{
public Curved4K65LEDTVBuilder()
{
television = new Television();
}
public override void SetCode()
{
television.Code = "Curved4K65LEDTV";
}
public override void SetDisplayTechnology()
{
television.DisplayTechnology = "LED";
}
public override void SetHDFormat()
{
television.HDFormat = "4K Ultra HD";
}
public override void SetScreenType()
{
television.ScreenType="Curved";
}
public override void SetSize()
{
television.Size="65";
}
public override void SetFeature()
{
television.Feature="3 HDMI Ports, 2 USB Ports,
Built in WIFI, Ethernet, Smart Remote";
}
}
Defining LCD22TVBuilder
(ConcreteBuilder4
) with respective implementation.
class LCD22TVBuilder : TelevisionBuilder
{
public LCD22TVBuilder()
{
television = new Television();
}
public override void SetCode()
{
television.Code = "LCD22TV";
}
public override void SetDisplayTechnology()
{
television.DisplayTechnology = "LCD";
}
public override void SetHDFormat()
{
television.HDFormat = "None";
}
public override void SetScreenType()
{
television.ScreenType = "Flat";
}
public override void SetSize()
{
television.Size = "22";
}
public override void SetFeature()
{
television.Feature = "Remote";
}
}
As of now, we have defined Product
, Builder
and ConcreteBuilder
. Now let's create TelevisionManufacturer
as the Director
, here the argument is Builder
, and the Director
takes care of calling the steps based on the requirement.
class TelevisionManufacturer
{
public void Construct(TelevisionBuilder televisionBuilder)
{
televisionBuilder.SetCode();
televisionBuilder.SetDisplayTechnology();
televisionBuilder.SetHDFormat();
televisionBuilder.SetScreenType();
televisionBuilder.SetSize();
televisionBuilder.SetFeature();
}
}
I have created a console Program
to test the Builder Pattern sample, here the end client is not at all worried about the complex object creation.
class Program
{
static void Main(string[] args)
{
TelevisionBuilder builder;
TelevisionManufacturer director = new TelevisionManufacturer();
builder = new FullHD40TVBuilder();
director.Construct(builder);
Television product1 = builder.Television;
Console.WriteLine("Code:{0}", product1.Code);
builder = new SMARTLED54TVBuilder();
director.Construct(builder);
Television product2 = builder.Television;
Console.WriteLine("Code:{0}", product2.Code);
builder = new Curved4K65LEDTVBuilder();
director.Construct(builder);
Television product3 = builder.Television;
Console.WriteLine("Code:{0}", product3.Code);
builder = new LCD22TVBuilder();
director.Construct(builder);
Television product4 = builder.Television;
Console.WriteLine("Code:{0}", product4.Code);
Console.ReadKey();
}
}
Output
Some code has been removed from the above Console.Writeline
to make the code look simple. You can refer to Program.cs file in the attached project to see the final version.
To explore this sample yourself, you can download the attached code or create a console project named "BuilderPatternSample
" and replace the content of Program.cs with the below code block.
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BuilderPatternSample
{
class Program
{
static void Main(string[] args)
{
TelevisionBuilder builder;
TelevisionManufacturer director = new TelevisionManufacturer();
builder = new FullHD40TVBuilder();
director.Construct(builder);
Television product1 = builder.Television;
Console.WriteLine(" ┌───────────────────────────────────Code:{0}───────────────────────────────┐",
product1.Code);
Console.WriteLine(" │ DisplayTechnology:{0} │",
product1.DisplayTechnology);
Console.WriteLine(" │ HDFormat:{0} │",
product1.HDFormat);
Console.WriteLine(" │ ScreenType:{0} │",
product1.ScreenType);
Console.WriteLine(" │ Size:{0} │",
product1.Size);
Console.WriteLine(" │ Feature:{0} │", product1.Feature);
Console.WriteLine(" └─────────────────────────────────────────────────────────────────────────────────┘");
builder = new SMARTLED54TVBuilder();
director.Construct(builder);
Television product2 = builder.Television;
Console.WriteLine(" ┌──────────────────────────────────Code:{0}──────────────────────────────┐",
product2.Code);
Console.WriteLine(" │ DisplayTechnology:{0} │",
product2.DisplayTechnology);
Console.WriteLine(" │ HDFormat:{0} │",
product2.HDFormat);
Console.WriteLine(" │ ScreenType:{0} │",
product2.ScreenType);
Console.WriteLine(" │ Size:{0} │",
product2.Size);
Console.WriteLine(" │ Feature:{0} │", product2.Feature);
Console.WriteLine(" └─────────────────────────────────────────────────────────────────────────────────┘");
builder = new Curved4K65LEDTVBuilder();
director.Construct(builder);
Television product3 = builder.Television;
Console.WriteLine(" ┌─────────────────────────────────Code:{0}────────────────────────────┐",
product3.Code);
Console.WriteLine(" │ DisplayTechnology:{0} │",
product3.DisplayTechnology);
Console.WriteLine(" │ HDFormat:{0} │",
product3.HDFormat);
Console.WriteLine(" │ ScreenType:{0} │",
product3.ScreenType);
Console.WriteLine(" │ Size:{0} │",
product3.Size);
Console.WriteLine(" │ Feature:{0} │", product3.Feature);
Console.WriteLine(" └─────────────────────────────────────────────────────────────────────────────────┘");
builder = new LCD22TVBuilder();
director.Construct(builder);
Television product4 = builder.Television;
Console.WriteLine(" ┌────────────────────────────────────Code:{0}─────────────────────────────────┐",
product4.Code);
Console.WriteLine(" │ DisplayTechnology:{0} │",
product4.DisplayTechnology);
Console.WriteLine(" │ HDFormat:{0} │",
product4.HDFormat);
Console.WriteLine(" │ ScreenType:{0} │",
product4.ScreenType);
Console.WriteLine(" │ Size:{0} │",
product4.Size);
Console.WriteLine(" │ Feature:{0} │",
product4.Feature);
Console.WriteLine(" └─────────────────────────────────────────────────────────────────────────────────┘");
Console.ReadKey();
}
}
class Television
{
public string Code { get; set; }
public string DisplayTechnology { get; set; }
public string HDFormat { get; set; }
public string ScreenType { get; set; }
public string Size { get; set; }
public string Feature { get; set; }
}
abstract class TelevisionBuilder
{
protected Television television;
public abstract void SetCode();
public abstract void SetDisplayTechnology();
public abstract void SetHDFormat();
public abstract void SetScreenType();
public abstract void SetSize();
public abstract void SetFeature();
public Television Television
{
get { return television; }
}
}
class FullHD40TVBuilder : TelevisionBuilder
{
public FullHD40TVBuilder()
{
television = new Television();
}
public override void SetCode()
{
television.Code = "FullHD40TV";
}
public override void SetDisplayTechnology()
{
television.DisplayTechnology = "LCD";
}
public override void SetHDFormat()
{
television.HDFormat = "FullHD";
}
public override void SetScreenType()
{
television.ScreenType = "Flat";
}
public override void SetSize()
{
television.Size = "40";
}
public override void SetFeature()
{
television.Feature = "1 HDMI Ports, 1 USB Ports, Remote";
}
}
class SMARTLED54TVBuilder : TelevisionBuilder
{
public SMARTLED54TVBuilder()
{
television = new Television();
}
public override void SetCode()
{
television.Code = "SMARTLED54TV";
}
public override void SetDisplayTechnology()
{
television.DisplayTechnology = "LED";
}
public override void SetHDFormat()
{
television.HDFormat = "FullHD";
}
public override void SetScreenType()
{
television.ScreenType = "Flat";
}
public override void SetSize()
{
television.Size = "54";
}
public override void SetFeature()
{
television.Feature = "2 HDMI Ports,
2 USB Ports, Built in WIFI, Ethernet, Remote";
}
}
class Curved4K65LEDTVBuilder : TelevisionBuilder
{
public Curved4K65LEDTVBuilder()
{
television = new Television();
}
public override void SetCode()
{
television.Code = "Curved4K65LEDTV";
}
public override void SetDisplayTechnology()
{
television.DisplayTechnology = "LED";
}
public override void SetHDFormat()
{
television.HDFormat = "4K Ultra HD";
}
public override void SetScreenType()
{
television.ScreenType = "Curved";
}
public override void SetSize()
{
television.Size = "65";
}
public override void SetFeature()
{
television.Feature = "3 HDMI Ports, 2 USB Ports, Built in WIFI,
Ethernet, Smart Remote";
}
}
class LCD22TVBuilder : TelevisionBuilder
{
public LCD22TVBuilder()
{
television = new Television();
}
public override void SetCode()
{
television.Code = "LCD22TV";
}
public override void SetDisplayTechnology()
{
television.DisplayTechnology = "LCD";
}
public override void SetHDFormat()
{
television.HDFormat = "None";
}
public override void SetScreenType()
{
television.ScreenType = "Flat";
}
public override void SetSize()
{
television.Size = "22";
}
public override void SetFeature()
{
television.Feature = "Remote";
}
}
class TelevisionManufacturer
{
public void Construct(TelevisionBuilder televisionBuilder)
{
televisionBuilder.SetCode();
televisionBuilder.SetDisplayTechnology();
televisionBuilder.SetHDFormat();
televisionBuilder.SetScreenType();
televisionBuilder.SetSize();
televisionBuilder.SetFeature();
}
}
}
Summary
In this article, I have explained Builder Pattern with a simple C# application. I hope you have enjoyed this article and got some value addition to your knowledge. Please don't forget to mark your votes, suggestions and feedback to improve the quality of this and upcoming articles.
History
- 29th February, 2016: Initial version