Builder design pattern falls under the category of "Creational" design patterns. This pattern is used to build a complex object by using a step by step approach.
GOF (Gang of Four) says:
“Separate the construction of a complex object from its representation so that the same construction process can create different representations”
So, it is used to construct a complex object step by step and the final step returns the object. Also, the process of constructing an object should be generic so that it can be used to create different representations of the same object.
Now, let’s see the UML diagram of it.
Below are the main parts of the UML diagram,
Builder
This is an interface which is used to define all the steps required to create a product.
ConcreteBuilder
This is a class which implements the Builder interface to create a complex product.
Product
This is a class which defines the parts of the complex object which are to be generated by the Builder Pattern.
Director
This is a class that is used to construct an object using the Builder interface.
So far, we have understood the UML diagram and the definition with its purpose. Now, it is time to look into the actual code to get a better understanding. So now, let’s see this with an example.
In the example shown below, we will be seeing how we can use this pattern to construct different parts of a toy.
This is our IToyBuilder interface which will be implemented by the ConcreteBuilder classes.
- public interface IToyBuilder {
- void SetModel();
- void SetHead();
- void SetLimbs();
- void SetBody();
- void SetLegs();
- Toy GetToy();
- }
This is the product class for Toy.
- public class Toy {
- public string Model {
- get;
- set;
- }
- public string Head {
- get;
- set;
- }
- public string Limbs {
- get;
- set;
- }
- public string Body {
- get;
- set;
- }
- public string Legs {
- get;
- set;
- }
- }
Below, we have 2 concrete classes for our two types of toys.
Toy A
- public class ToyABuilder: IToyBuilder {
- Toy toy = new Toy();
- public void SetModel() {
- toy.Model = "TOY A";
- }
- public void SetHead() {
- toy.Head = "1";
- }
- public void SetLimbs() {
- toy.Limbs = "4";
- }
- public void SetBody() {
- toy.Body = "Plastic";
- }
- public void SetLegs() {
- toy.Legs = "2";
- }
- public Toy GetToy() {
- return toy;
- }
- }
Toy B
- public class ToyBBuilder: IToyBuilder {
- Toy toy = new Toy();
- public void SetModel() {
- toy.Model = "TOY B";
- }
- public void SetHead() {
- toy.Head = "1";
- }
- public void SetLimbs() {
- toy.Limbs = "4";
- }
- public void SetBody() {
- toy.Body = "Steel";
- }
- public void SetLegs() {
- toy.Legs = "4";
- }
- public Toy GetToy() {
- return toy;
- }
- }
Let’s see the final director class which will be responsible for the construction of an object using the Builder Interface.
- public class ToyCreator {
- private IToyBuilder _toyBuilder;
- public ToyCreator(IToyBuilder toyBuilder) {
- _toyBuilder = toyBuilder;
- }
- public void CreateToy() {
- _toyBuilder.SetModel();
- _toyBuilder.SetHead();
- _toyBuilder.SetLimbs();
- _toyBuilder.SetBody();
- _toyBuilder.SetLegs();
- }
- public Toy GetToy() {
- return _toyBuilder.GetToy();
- }
- }
Finally, below is the main method of our program.
- void Main() {
- Console.WriteLine("-------------------------------List Of Toys--------------------------------------------");
- var toyACreator = new ToyCreator(new ToyABuilder());
- toyACreator.CreateToy();
- toyACreator.GetToy().Dump();
- var toyBCreator = new ToyCreator(new ToyBBuilder());
- toyBCreator.CreateToy();
- toyBCreator.GetToy().Dump();
- }
OUTPUT
Now, let’s understand when we should use this pattern with its advantages and disadvantages.
WHEN TO USE THIS PATTERN
We need to create a complex object in several steps (a step by step approach).
ADVANTAGES
- Code is more maintainable and readable.
- Less prone to errors as we have a method which returns the finally constructed object.
DISADVANTAGES
Number of lines of code increases in builder pattern, but it makes sense as the effort pays off in terms of maintainability and readability.
Conclusion
You should not use builder pattern just because it is a design pattern as no one should follow the best practice just because it is a best practice.
So, if your object has only a few constructor arguments, it makes no sense to use the builder pattern.
Builder pattern is a good choice when designing classes whose constructors have more than a handful of parameters.
Consider builder pattern when faced with many constructor parameters, some of which are also optional. Using this code becomes much easier to read and write as compared to the traditional constructor pattern.
I hope you find this article helpful. Stay tuned for more … Cheers!!
You can also check out some of my previous articles,