Design Patterns – Builder
Hi guys! Today I want to speak a bit about the Builder Pattern.
This pattern allows for creating complex objects. First, we can create each part of the object (step by step) and finally, we will join all the parts together to get the final object.
This is another Creational Design Pattern which helps us to attack the following points:
- A lot of parameters in the constructors (because we have to create complex objects) –> MAIN REASON
- Order dependent
Let’s begin!
Business Situation
We work in a Company that makes Developers.
At the moment this company only make Dotnet Senior Fullstack Developers.
(Yeahh this example is based in the dream of an IT recruiter friend jaja)
For this reason, our system should allow modelling this kind of developer.
Step1: code fast 🙁
First, we code the Developer Class:
In this step, we have the following constructor:
You can see as we have a constructor with too many parameters because we make developer, it is not an easy task!
Can you imagine if tomorrow we need to create a backend semi-senior developer?
In this case, we can see like we are depending of parameters to create others dev flavours. At the moment, this is not a problem for us because we just create Dotnet Senior Fullstack developers.
Step2: Refactoring 1 – attacking complex constructors 🙂
We have a secret recipe to create developers, we follow these steps:
- Focus in a language: Do you like dotnet? Do you prefer Java or NodeJs?
- Select your side: Do you prefer backend side? frontend side? or maybe, you’re a full-stack ninja?
- Get experience: Work hard, mate! Apply your knowledge in the real world!
To create any developer, we need to implement the above steps!
Ok, let’s try to build a basic builder. Our builder has the recipe to make Developers.
In this case, the developer-builder knows to create only Dotnet Senior Fullstack Developers! It isn’t scalable but it complies with our business requirements!
Let’s looks at our DevBuilder class:
class DeveloperBuilder
{
Developer developer;
public Developer GetDeveloper()
{
return developer;
}
public void CreateDeveloper(string name, string surname)
{
developer = new Developer(name, surname);
FocusInALanguage();
SelectYourSide();
GetExperience();
}
private void GetExperience()
{
developer.Seniority = eSeniority.Senior;
}
private void SelectYourSide()
{
developer.Type = eDevType.Fullstack;
}
private void FocusInALanguage()
{
developer.Technology = eTechnology.Dotnet;
}
Our DeveloperBuilder is expert creating DotNet Fullstack senior developers, nice;)
Ok, we achieve to attack the big constructor 😉
Step3: Refactoring – Builder Pattern 😀
Yesterday, the CEO called to said to us: “Franco we will expand our business! We need to make Java Junior Backend Developers too!”
Ok, I think “Bad, really bad. Java developers here? I hate them!” jajaj I joke, mate :p
Ok, we use the Builder Design Pattern for modelling that.
Structure:
Explain:
- Builder: declare all steps to create a specific object but just declare them. We don’t specify sort or implementation here.
- ConcreteBuilders: Here we implement all steps to build the specific object.
- Products: These products are built with the builders. In other words, builders return different flavours about the same class.
- Director: Define the specific order to create the objects.
- Use the concrete builders
- Knows how to build –> Knows the magic recipe! The correct order of the steps
- The client can call him directly
Our developer class doesn’t have any change.
First, we create DeveloperBuilder Abstract Class, remember that we could create an IDeveloperBuilder Interface too (it’s another good way). The builder has the necessary methods to create Developers but here, we don’t specify the sort about these!
Then, we code the DotNetSeniorFullStackDevBuilder class to create this kind of developers 😉
Then, we code the JavaJuniorBackendBuilder class to create Java juniors devs:
Finally, we need to create our Director. For us, the Director will be the IT Recruiter. He/She will make the developers!
The Director has the recipe to create Developers! The correct steps in the correct order!
Ok, Let’s look at the main program:
Plus: variations – Fluent builder 😉
The original approach is great, but we can use another flavour. This alternative is called Fluent Builder.
To use this alternative we need to modify our Developer Class and create a Developer Builder class!
class Developer
{
public string Name { get; private set; }
public string Surname { get; private set; }
public eDevType Type { get; set; }
public eSeniority Seniority { get; set; }
public eTechnology Technology { get; set; }
public Developer() { }
public Developer(string name, string surname)
{
Name = name;
Surname = surname;
}
public void Print()
{
Console.WriteLine($"Name: { Name } - Surname: { Surname } - Type: { Type.ToString() } - Seniority: { Seniority.ToString() } - Technology: { Technology.ToString() }");
}
public static DeveloperBuilder Builder()
{
return new DeveloperBuilder();
}
public class DeveloperBuilder
{
private string Name;
private string Surname;
private eDevType Type;
private eSeniority Seniority;
private eTechnology Technology;
public DeveloperBuilder SetCompleteName(string name, string surname)
{
Name = name;
Surname = surname;
return this;
}
public DeveloperBuilder SetType(eDevType type)
{
Type = type;
return this;
}
public DeveloperBuilder SetSeniority(eSeniority seniority)
{
Seniority = seniority;
return this;
}
public DeveloperBuilder SetTechnology(eTechnology technology)
{
Technology = technology;
return this;
}
public Developer Build()
{
Developer developer = new Developer(Name, Surname);
developer.Seniority = Seniority;
developer.Technology = Technology;
developer.Type = Type;
return developer;
}
}
}
Finally, we can do the following to create developers:
This focus is not bad, but we are delegating the recipe to the client. The client needs to know the correct sorting and steps to create developers, maybe that can be dangerous.
That’s all, mates!
You can see all the code on my github
Big hug!
2 thoughts on “Design Patterns – Builder”
Leave a Reply
You must be logged in to post a comment.
For fluent builder, do you put two classes in one file?
Can we do it separately?
What is the different?
Yes, you can separate the builder in 2 classes when I use to this approach, I create the builder class in another file, then I reference this class in the model. For example, I create a StudentClass and in another file a StudentBuilderClass, finally StudentClass will reference the StudentBuilderClass.
In my opinion, the difference is the clarity and order in the code maybe you can put all builder in a builderFolder, but that’s all because always the builders will be coupled with their model classes.