Design Patterns — Builder Pattern Made EASY in Java

Rana M. Suleman
3 min readMar 22, 2021

Here we will be looking at Joshua’s Bloch Builder design pattern.

Design patterns are the solutions to the same standard problems that are faced on so many occasions by the developers. And this pattern discusses one of those problems.

Let’s go with an example to understand the case:

You are given an Employee class with some fields like first_name and last_name which are required. (Obviously, why wouldn’t they be ?)

public class Employee{String first_name; //required field
String last_name: //required field
Employee(String first_name , String last_name){
this.first_name = first_name;
this.last_name = last_name;
}
}

Now if we have to add more fields like favourite_hobby, martial_status & middle_name which are optional.

public class Employee{String first_name; //required field
String last_name: //required field
String middle_name; //optional_field
String favourite_hobby; //optional field
String martial_status; //optional field
Employee(String first_name , String last_name){
this.first_name = first_name;
this.last_name = last_name;
}
}

Now if you introduce these variables as parameters in the existing constructor, you will be forced to make changes wherever you have called this constructor.

So, what could be done to parameterized these new fields and also not to make any changes in the existing code?

We make a new constructor with added params. Right!

Let see this

public class Employee{String first_name; //required field
String last_name: //required field
String middle_name; //optional_field
String favourite_hobby; //optional field
String martial_status; //optional field
Employee(String first_name , String last_name){
this.first_name = first_name;
this.last_name = last_name;
}
Employee(String first_name , String last_name , String middle_name , String favourite_hobby ,String martial_status){this.first_name = first_name;
this.last_name = last_name;
this.middle_name = middle_name;
this.favourite_hobby = favourite_hobby;
this.martial_status = martial_status;
}
}

but what if in some cases only three fields needed to be initialized like first_name, last_name & middle_name.

We can pass the null value:

Employee emp = new Employee("Barry", "Allen", "John" , null , null);

Or we could create a new constructor with those fields and keep things neat.

public class Employee{String first_name; //required field
String last_name: //required field
String middle_name; //optional_field
String favourite_hobby; //optional field
String martial_status; //optional field
Employee(String first_name , String last_name){
this.first_name = first_name;
this.last_name = last_name;
}
Employee(String first_name , String last_name , String middle_name , String favourite_hobby ,String martial_status){this.first_name = first_name;
this.last_name = last_name;
this.middle_name = middle_name;
this.favourite_hobby = favourite_hobby;
this.martial_status = martial_status;
}
Employee(String first_name,String last_name,String middle_name){this.first_name = first_name;
this.last_name = last_name;
this.middle_name = middle_name;
}
}

Call on the newly created constructor

Employee = new Employee("Barry", "Allen", "John")

But there is another variable that is introduced Salary.

So, another constructor?

With that with creating more and more constructors with different combinations, there will be a time where you could not create the constructor with desired params because of the method signature being the same.

For example:

public class Employee{String first_name; //required field
String last_name: //required field
String middle_name; //optional_field
String favourite_hobby; //optional field
String martial_status; //optional field
Employee(String first_name , String last_name){
this.first_name = first_name;
this.last_name = last_name;
}
Employee(String first_name , String last_name , String middle_name , String favourite_hobby ,String martial_status){this.first_name = first_name;
this.last_name = last_name;
this.middle_name = middle_name;
this.favourite_hobby = favourite_hobby;
this.martial_status = martial_status;
}
Employee(String first_name,String last_name,String middle_name){this.first_name = first_name;
this.last_name = last_name;
this.middle_name = middle_name;
}
//this constructor have the same signature as above one
Employee(String first_name,String last_name,String martial_status){
this.first_name = first_name;
this.last_name = last_name;
this.martial_status = martial_status;
}
}

The Builder pattern provides us a way to handle these problems.

Let’s look at the implementation

public class Employee {

private String first_name; //required field
private String last_name; //required field
private String middle_name; //optional_field
private String favourite_hobby; //optional field
private String martial_status; //optional field

Employee(EmployeeBuilder builder) {
this.first_name = builder.first_name;
this.last_name = builder.last_name;
this.middle_name = builder.middle_name;
this.favourite_hobby = builder.favourite_hobby;
this.martial_status = builder.martial_status;
}


public static class EmployeeBuilder {
private String first_name; //required field
private String last_name; //required field
private String middle_name; //optional_field
private String favourite_hobby; //optional field
private String martial_status; //optional field

public EmployeeBuilder first_name(String first_name) {
this.first_name = first_name;
return this;
}

public EmployeeBuilder last_name(String last_name) {
this.last_name = last_name;
return this;
}

public EmployeeBuilder middle_name(String middle_name) {
this.middle_name = middle_name;
return this;
}

public EmployeeBuilder favourite_hobby(String favourite_hobby) {
this.favourite_hobby = favourite_hobby;
return this;
}

public EmployeeBuilder martial_status(String martial_status) {
this.martial_status = martial_status;
return this;
}
public Employee build() {
Employee emp = new Employee(this);
return emp;
}
}

}

And this how it will be used:

Employee emp = new Employee.EmployeeBuilder
.first_name("Ben")
.middle_name("John")
.last_name("Atkins")
.martial_status("married");
.build();

As you can see we didn’t use all the fields and also their order doesn’t matter here.

So we can now make objects without creating constructors for every field and also we don’t have to pass null for the fields we don’t require.

For more: www.buffernest.com

--

--

Rana M. Suleman

Business oriented technology enthusiast, sharing ideas from the idea valley inside my immensely curious mind, A boring Software developer and a Gaming Nerd