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:

developer class

In this step, we have the following constructor:

Creating a dotnet fullstack developer

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?

Creating another flavour

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:

  1. Focus in a language: Do you like dotnet? Do you prefer Java or NodeJs?
  2. Select your side: Do you prefer backend side? frontend side? or maybe, you’re a full-stack ninja?
  3. 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;)

main program!

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:

  1. Builder: declare all steps to create a specific object but just declare them. We don’t specify sort or implementation here.
  2. ConcreteBuilders: Here we implement all steps to build the specific object.
  3. Products: These products are built with the builders. In other words, builders return different flavours about the same class.
  4. Director: Define the specific order to create the objects.
    1. Use the concrete builders
    2. Knows how to build –> Knows the magic recipe! The correct order of the steps
    3. 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!

recipe!

Then, we code the DotNetSeniorFullStackDevBuilder class to create this kind of developers 😉

dotnet builder

Then, we code the JavaJuniorBackendBuilder class to create Java juniors devs:

Java builder

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!

Director!

Ok, Let’s look at the main program:

build developers!

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:

Fluent Builder

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!