Introduction
The Builder Pattern is among the Creational Patterns of the Gang Of Four (GOF). To understand this pattern, we first need to understand its intent.
Intent
“Separate the construction of a complex object from its representation so that the same construction process can create different representations.” –GOF
The preceding definition of the Builder Design Pattern is given by the GOF. It might be difficult to understand by reading the definition, so let us understand it by dividing it up.
So the moral of the story is "Separate object construction from its representation".
Now let's understand the implementation of this pattern using a real-world scenario.
Scenario
On one fine day a Pizza vendor has placed an order to a software company. His requirement was to get the list of contents to make a Pizza based on the requested Pizza type. The company has accepted the order and has provided this definition to his Project Manager Mr. X. Then Mr. X has explained all the requirements to his developer Mr. Y and asked him to develop a program for that.
Approach 1
Mr. Y has begun thinking of the definition. He thought that there are many possible contents in a Pizza, like size, dough type, cheese type and so on. So first he created enumerations for all these selections. Then he created one class called "Pizza". In this class he has created a parameterized constructor with all required contents to create the Pizza. This constructor accepts the contents and sets the values in private variables. Now Mr. X has accept the functionality for the contents from the client, so he created a method called "PizzaContent" to print the entire list of contents to generate the Pizza.
- public class Pizza
- {
- private readonly DoughType doughType;
- private readonly bool isRedPepper;
- private readonly Size size;
- private readonly CheeseType cheeseType;
- private readonly List<string> vegetables;
- public Pizza(DoughType doughType, bool isRedPepper, Size size,CheeseType cheeseType,List<string> vegetables)
- {
- this.doughType = doughType;
- this.isRedPepper = isRedPepper;
- this.size=size;
- this.cheeseType=cheeseType;
- this.vegetables=vegetables;
- }
- public void PizzaContent()
- {
- Console.WriteLine("Pizza with {0}", doughType);
- if (isRedPepper)
- Console.WriteLine("Red Pepper");
- Console.WriteLine("Size: {0}", size);
- Console.WriteLine("Cheese Type: {0}", cheeseType);
- Console.WriteLine("Vegetables:");
- foreach (var item in vegetables)
- {
- Console.WriteLine(" {0}", item);
- }
- }
- }
- public enum DoughType
- {
- Neapolitan_Pizza_Dough = 1,
- NewYorkStyle_Pizza_Dough = 2,
- SquarePan_Pizza_Dough = 3
- }
- public enum CheeseType
- {
- American = 1,
- Swiss = 2,
- }
- public enum Size
- {
- Small = 1,
- Medium = 2,
- Large = 3
- }
Mr. Y has created an object of the Pizza class where he has provided the contents of his choice to create a Pizza and called the method to get the contents.
- static void Main(string[] args)
- {
- new Pizza(DoughType.Neapolitan_Pizza_Dough, true, Size.Medium, CheeseType.Swiss, new List<string> { "Tomato", "Capsicum","Corn" }).PizzaContent();
- Console.ReadKey();
- }
Mr. Y has checked the application and it was built and run successfully.

Mr. Y was very happy that he has completed the given task successfully. He has provided the demo to his Project Manager Mr. X. Mr. X has gone through the application and has discovered a problem. The constructor is very large, in other words the constructor has many parameters. He asked Mr. Y to solve that problem.

Huge Constructor / Too many parameters
Approach 2
Again Mr. Y has started working on it. He has made some changes in the Pizza class. He has converted a variable into properties and removed the parameterized constructor.
- public class Pizza
- {
- public DoughType doughType {get; set;}
- public bool isRedPepper { get; set; }
- public Size size { get; set; }
- public CheeseType cheeseType { get; set; }
- public List<string> vegetables { get; set; }
- public void PizzaContent()
- {
- Console.WriteLine("Pizza with {0}", doughType);
- if (isRedPepper)
- Console.WriteLine("Red Pepper");
- Console.WriteLine("Size: {0}", size);
- Console.WriteLine("Cheese Type: {0}", cheeseType);
- Console.WriteLine("Vegetables:");
- foreach (var item in vegetables)
- {
- Console.WriteLine(" {0}", item);
- }
- }
- }
- public enum DoughType
- {
- Neapolitan_Pizza_Dough = 1,
- NewYorkStyle_Pizza_Dough = 2,
- SquarePan_Pizza_Dough = 3
- }
- public enum CheeseType
- {
- American = 1,
- Swiss = 2,
- }
- public enum Size
- {
- Small = 1,
- Medium = 2,
- Large = 3
- }
Mr. Y has created an object of the Pizza class and has set all the properties for that object and called the method.
- static void Main(string[] args)
- {
- var pizza = new Pizza();
- pizza.doughType = DoughType.Neapolitan_Pizza_Dough;
- pizza.isRedPepper = true;
- pizza.size = Size.Large;
- pizza.cheeseType = CheeseType.American;
- pizza.vegetables = new List<string> { "Tomato", "Corn" };
- pizza.PizzaContent();
- Console.ReadKey();
- }
Mr. Y has built and run the application again.

This time Mr. Y thought that he has solved the problem. He has shown the application to his Project Manager Mr. X. Mr. X was a little happy but explained that the client needs to remember all the properties, so you need to figure out some solution.

Need to remember all the properties
Approach 3
Mr. Y has again started working on that and he got the solution for not remembering the properties. This time he didn't change anything in the Pizza class.
- public class Pizza
- {
- public DoughType doughType {get; set;}
- public bool isRedPepper { get; set; }
- public Size size { get; set; }
- public CheeseType cheeseType { get; set; }
- public List<string> vegetables { get; set; }
- public void PizzaContent()
- {
- Console.WriteLine("Pizza with {0}", doughType);
- if (isRedPepper)
- Console.WriteLine("Red Pepper");
- Console.WriteLine("Size: {0}", size);
- Console.WriteLine("Cheese Type: {0}", cheeseType);
- Console.WriteLine("Vegetables:");
- foreach (var item in vegetables)
- {
- Console.WriteLine(" {0}", item);
- }
- }
- }
- public enum DoughType
- {
- Neapolitan_Pizza_Dough = 1,
- NewYorkStyle_Pizza_Dough = 2,
- SquarePan_Pizza_Dough = 3
- }
- public enum CheeseType
- {
- American = 1,
- Swiss = 2,
- }
- public enum Size
- {
- Small = 1,
- Medium = 2,
- Large = 3
- }
- Create one method "GetPizza" that returns an instance of a Pizza class
- Create methods ("PrepareDough", "AppyVegetables", "AppyCheese", "AddCondiments") to set properties
- Create one more method "CreatePizza" that initializes an object of the Pizza class and calls the preceding methods
- public class MyPizzaBuilder
- {
- Pizza pizza;
- public Pizza GetPizza()
- {
- return pizza;
- }
- public void CreatePizza()
- {
- pizza = new Pizza();
- PrepareDough();
- ApplyVegetables();
- ApplyCheese();
- AddCondiments();
- }
- private void AddCondiments()
- {
- pizza.isRedPepper = true;
- }
- private void ApplyCheese()
- {
- pizza.cheeseType = CheeseType.American;
- }
- private void ApplyVegetables()
- {
- pizza.vegetables = new List<string> { "Tomato", "Corn" };
- }
- private void PrepareDough()
- {
- pizza.doughType = DoughType.Neapolitan_Pizza_Dough;
- pizza.size = Size.Large;
- }
- }
- static void Main(string[] args)
- {
- var builder = new MyPizzaBuilder();
- builder.CreatePizza();
- var pizza = builder.GetPizza();
- pizza.PizzaContent();
- Console.ReadKey();
- }
Again Mr. Y has built and run the application and was very happy. He just explained the solution to his Project Manager. The Project Manager appreciated his efforts and asked one question "What if we want to create another type of Pizza?" Mr. Y was realized that he must copy "MyPizzaBuilder" and then change the definition of creating a Pizza.


If you want to create another type of Pizza then you need to create another class and copy from MyPizzaBuilder and change the definition of creating a Pizza. This is not a good practice.
Approach 4
Mr. Y has become fed up with the situation and this time he just wants a concrete solution. So he has thought about it and came up with the solution. In this approach he also didn't change anything in the "Pizza" class.
- public class Pizza
- {
- public DoughType doughType {get; set;}
- public bool isRedPeeper { get; set; }
- public Size size { get; set; }
- public CheeseType cheeseType { get; set; }
- public List<string> vegetables { get; set; }
- public void PizzaContent()
- {
- Console.WriteLine("Pizza with {0}", doughType);
- if (isRedPeeper)
- Console.WriteLine("Red Peeper");
- Console.WriteLine("Size: {0}", size);
- Console.WriteLine("Cheese Type: {0}", cheeseType);
- Console.WriteLine("Vegetables:");
- foreach (var item in vegetables)
- {
- Console.WriteLine(" {0}", item);
- }
- }
- }
- public enum DoughType
- {
- Neapolitan_Pizza_Dough = 1,
- NewYorkStyle_Pizza_Dough = 2,
- SquarePan_Pizza_Dough = 3
- }
- public enum CheeseType
- {
- American = 1,
- Swiss = 2,
- }
- public enum Size
- {
- Small = 1,
- Medium = 2,
- Large = 3
- }
- public abstract class PizzaBuilder
- {
- protected Pizza pizza;
- public Pizza GetPizza()
- {
- return pizza;
- }
- public void CreateNewPizza()
- {
- pizza = new Pizza();
- }
- public abstract void PrepareDough();
- public abstract void ApplyVegetables();
- public abstract void ApplyCheese();
- public abstract void AddCondiments();
- }
- public class MyPizzaBuilder : PizzaBuilder
- {
- public override void AddCondiments()
- {
- pizza.isRedPeeper = true;
- }
- public override void ApplyCheese()
- {
- pizza.cheeseType = CheeseType.American;
- }
- public override void ApplyVegetables()
- {
- pizza.vegetables = new List<string> { "Tomato", "Corn" };
- }
- public override void PrepareDough()
- {
- pizza.doughType = DoughType.Neapolitan_Pizza_Dough;
- pizza.size = Size.Large;
- }
- }
- public class PizzaMaker
- {
- private readonly PizzaBuilder builder;
- public PizzaMaker(PizzaBuilder builder)
- {
- this.builder = builder;
- }
- public void BuildPizza()
- {
- builder.CreateNewPizza();
- builder.PrepareDough();
- builder.ApplyVegetables();
- builder.ApplyCheese();
- builder.AddCondiments();
- }
- public Pizza GetPizza()
- {
- return builder.GetPizza();
- }
- }

Participants
- Builder (PizzaBuilder): Specifies an abstract interface for creating parts of a Product object.
- ConcreteBuilder (MyPizzaBuilder, TomatoPizzaBuilder): Constructs and assembles parts of the product by implementing the Builder interface and defines and keeps track of the representation it creates. Provides an interface for retrieving the product.
- Director (PizzaMaker): Constructs an object using the Builder interface.
- Product (Pizza): Represents the complex object under construction. ConcreteBuilder builds the product's internal representation and defines the process by which it's assembled includes classes that define the constituent parts, including interfaces for assembling the parts into the final result.
In the client-side code Mr. Y has created an object of the "PizzaMaker" class and passed a "MyPizzaBuilder" object. Then he called the BuildPizza method that calls all the necessary methods to create a Pizza for that builder. In the third step he called the GetPizza method followed by the PizzaContent method. The same was done for "TomatoPizzaBuilder" also.
- static void Main(string[] args)
- {
- var pizzaMaker = new PizzaMaker(new MyPizzaBuilder());
- pizzaMaker.BuildPizza();
- var pizza1 = pizzaMaker.GetPizza();
- pizza1.PizzaContent();
- pizzaMaker = new PizzaMaker(new TomatoPizzaBuilder());
- pizzaMaker.BuildPizza();
- var pizza2 = pizzaMaker.GetPizza();
- pizza2.PizzaContent();
- Console.ReadKey();
- }
Mr. Y has built and run the application and gave the demo to Mr. X.

This time Mr. X has gone through the application and was very happy as Mr Y. has implemented "The Builder Design Pattern".

Summary
When we have multiple parameters, the order of those parameters are important and when we have different constructions, we should need to separate the construction of an object from its representation.

सुनन्दा शर्माPosted Jun 24, 2020, 1:34 AM
Really explained very well with how does the need arise to come to the situation where we need the builder pattern. Keep up the good work.
Debasish TutuPosted Oct 11, 2018, 2:19 AM
Wonderful explanation. Could you please provide the difference or scenario where to use factory and where to use builder
SG PatelPosted Sep 30, 2018, 2:19 PM
This is very helpful.
Gowtham RajamanickamPosted Mar 30, 2015, 10:12 AM
good..
Asutosha SarangiPosted Mar 30, 2015, 7:42 AM
where is the interface ??
Siraz KhanPosted Mar 30, 2015, 4:58 AM
This is nice one and really helpfull.
Tom MohanPosted Mar 30, 2015, 4:46 AM
Interesting one
Rajeev RanjanPosted Mar 30, 2015, 4:19 AM
nice and superv ....
Kalpesh BhadraPosted Mar 30, 2015, 3:52 AM
this is really helpfull to unserstand OOP.... thanks for sharing akshay...
jignesh solankiPosted Mar 30, 2015, 3:48 AM
Good one
Saineshwar BageriPosted Mar 30, 2015, 12:27 AM
nice example sir