Builder Pattern with Java Lombok
By: Sidath Weerasinghe
Tags: Builder Pattern, Java, Lombok, Design Patterns, Architecture

Image source — https://stacktraceguru.com/builder-pattern

Most developers use the builder pattern to reduce the complexity of creating complex objects by giving the step by step approach. The builder pattern reduces the boilerplate codes in your program.

What are the problems we are going to solve from the builder pattern?

If we have several parameters on the constructor, it isn’t easy to remember the parameters’ order. Based on the application logic, sometimes we need to write to several constructors.

Suppose you want to create immutable classes, then better to use the builder pattern. The builder pattern gives immutable classes with a large set of state attributes.

If you have mandatory parameters and optional parameters, then you need to maintain several constructors. In this case, better to use the builder pattern.

Traditional way of implementation without builder pattern

public class Person {



private String firstName;

private String secondName;

private int age;

private String address;

private String idNumber;





public Person(String firstName) {

this.firstName = firstName;

}



public Person(String firstName, int age) {

this.firstName = firstName;

this.age = age;

}



public Person(String firstName, int age, String idNumber) {

this.firstName = firstName;

this.age = age;

this.idNumber = idNumber;

}



public Person(String firstName, String secondName, String address) {

this.firstName = firstName;

this.secondName = secondName;

this.address = address;

}



public Person(String firstName, String secondName, int age, String address, String idNumber) {

this.firstName = firstName;

this.secondName = secondName;

this.age = age;

this.address = address;

this.idNumber = idNumber;

}



public String getFirstName() {

return firstName;

}



public void setFirstName(String firstName) {

this.firstName = firstName;

}



public String getSecondName() {

return secondName;

}



public void setSecondName(String secondName) {

this.secondName = secondName;

}



public int getAge() {

return age;

}



public void setAge(int age) {

this.age = age;

}



public String getAddress() {

return address;

}



public void setAddress(String address) {

this.address = address;

}



public String getIdNumber() {

return idNumber;

}



public void setIdNumber(String idNumber) {

this.idNumber = idNumber;

}

}

By looking at the above code, you can see so many code lines (boilerplate code). The above class has several constructors with different parameters and the getter and setters for each variable.

Builder pattern traditional implementation

public class Person {



private String firstName;

private String secondName;

private int age;

private String address;

private String idNumber;



private Person(PersonBuilder builder) {

this.firstName = builder.firstName;

this.secondName = builder.secondName;

this.age = builder.age;

this.address = builder.address;

this.idNumber = builder.idNumber;

}



public String getFirstName() {

return firstName;

}



public String getSecondName() {

return secondName;

}



public int getAge() {

return age;

}



public String getAddress() {

return address;

}



public String getIdNumber() {

return idNumber;

}



public static class PersonBuilder {

private String firstName;

private String secondName;

private int age;

private String address;

private String idNumber;



public PersonBuilder firstName(String firstName) {

this.firstName = firstName;

return this;

}



public PersonBuilder secondName(String secondName) {

this.secondName = secondName;

return this;

}



public PersonBuilder age(int age) {

this.age = age;

return this;

}



public PersonBuilder address(String address) {

this.address = address;

return this;

}



public PersonBuilder idNumber(String idNumber) {

this.idNumber = idNumber;

return this;

}



public Person build() {

Person person = new Person(this);

return person;

}



}

}

Usage —

Person person = new Person.PersonBuilder()

.firstName("Sidath")

.secondName("Weerasinghe")

.age(26).build();

Lombok

Lombok is a small java library tool that reduces the boiler pate code in the java project using annotations. It improves the code readability and helps to reduce the lines of code in the program.

Any performance issue using Lombok ?

Lombok works on the java compile time, so there is no performance issue with the java runtime. Based on the annotations we are putting on the code base Lombok add all the boilerplate code according to that provided annotations to the .class files during the compilation time.

Builder pattern implementation with Lombok annotations

import lombok.Builder;

import lombok.Getter;



@Getter

@Builder

public class Person {



private String firstName;

private String secondName;

private int age;

private String address;

private String idNumber;

}

Usage —

Person person = new Person.PersonBuilder()

.firstName("Sidath")

.secondName("Weerasinghe")

.age(26).build();

Disadvantages of the builder pattern

You cant create mutable objects. (this can be also resolved by using the genetic builder using the java reflection)

Reference —