Builder design pattern in java

Builder design pattern in java is used to create a complex object. It is also part of a creational design pattern like an abstract factory design pattern. If you haven’t read the builder design pattern in java yet, then you should read it first. abstract factory design pattern

Here is the table content of the article will we will cover this topic.
1. Builder design pattern in java?
2. Why do we use the builder design pattern in java?
3. Implementation of builder pattern java?
4. Java builder pattern example?
5. Advantages of Builder Pattern?
6. Disadvantages of Builder Pattern?

As we know abstract factory design pattern and factory design pattern is used to create an object. But there is some problem that comes with the object created when a class has a large number of attributes. So, in this post, we will see what the problem with abstract factory pattern are and how to resolve them by builder pattern java.

Builder design pattern in java?

Builder design pattern in java?

The Builder design pattern is used to create a complex object by using a step-by-step approach. It is very helpful when you have a large number of attributes in class and you want to create an object. The Builder class creates the final object step by step and it is independent of other objects.

Let’s see what the problem comes with the Factory and Abstract Factory design pattern. When a class has a lot of attributes it faces the following problems:

1. We pass the arguments from the client program to the factory to create an object. But if we have a large number of arguments then it can be a headache because the type of arguments should be the same from the client side to the factory.

2. Some of the parameters might be optional but in the Factory pattern, but we have to send them as NULL.

In the next section, we will see how to resolve this problem by builder pattern java

Why do we use the builder design pattern in java?

1. Build design pattern is used to create and construct complex objects.

2. It is a way to build different immutable objects using the same object-building process.

The problem without Builder pattern

Suppose we are working on a project and we have a class Person having five attributes FirstName, LastName, Age, Phone, Address. Suppose we want to make an immutable object of the Person class. It means we will not change the state of the object after creation.

So, we have to provide a Constructor that will take all the properties.

public Person (String firstName, String lastName, int age, String phone, String address)
{
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
    this.phone = phone;
    this.address = address;
}

But now there is another problem if FirstName and LastName are mandatory and the rest of the fields are optional. Then we have to provide four more constructors.

public Person(String firstName, String lastName, int age, String phone){ ... }
public Person(String firstName, String lastName, String phone, String address){ ...  }
public Person(String firstName, String lastName, int age){ ...   }
public Person(String firstName, String lastName){ ...    }

But in the future, if we will add more attributes in class then we have to create more constructors. This approach is not good for a long-term project because we are writing unnecessary code.
If we create a setter method, then we will lose the immutability of the object.

The builder pattern helps us to resolve the above problems.

Implementation of builder pattern java

1. We have to create a  static nested class(Inner static class) that is known as Builder class. The builder class copies all the properties from the outer class to the Builder class.

NOTE: We should follow the naming convention. If we have a Person class then the name of the builder class should be PersonBuilder.

2. The Builder class will contain a public constructor only with the required attributes.

3. The Builder class will contain some setters for optional attributes and it will return the same Builder object.

4. The Builder class will have a build() method that will return the Object needed by the client program. For this, we need to have a private constructor in the Class with Builder class as an argument.

java builder pattern example

Here we will resolve the problem that we have discussed above. Here we are creating PersonBuilder class that will help us to build a Person object.

class Person 
{
    //All final attributes
    private final String firstName; // required
    private final String lastName; // required
    private final int age; // optional
    private final String phone; // optional
    private final String address; // optional
 
    private Person(PersonBuilder builder) 
    {
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.age = builder.age;
        this.phone = builder.phone;
        this.address = builder.address;
    }
 
    //All getter, and NO setter to provide immutability
    public String getFirstName() {
        return firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public int getAge() {
        return age;
    }
    public String getPhone() {
        return phone;
    }
    public String getAddress() {
        return address;
    }
    
    @Override
    public String toString() {
        return "Person: "+this.firstName+", "+this.lastName+", "+this.age+", "+this.phone+", "+this.address;
    }
 
    public static class PersonBuilder 
    {
        private final String firstName;
        private final String lastName;
        private int age;
        private String phone;
        private String address;
 
        public PersonBuilder(String firstName, String lastName) 
        {
            this.firstName = firstName;
            this.lastName = lastName;
        }
        public PersonBuilder age(int age) 
        {
            this.age = age;
            return this;
        }
        public PersonBuilder phone(String phone) 
        {
            this.phone = phone;
            return this;
        }
        public PersonBuilder address(String address) 
        {
            this.address = address;
            return this;
        }
        
        //Return the finally constructed Person object
        public Person build() 
        {
        	return new Person(this);
        }
        
    }
}
public class MainClass 
{
	public static void main(String[] args) 
	{
		Person person1 = new Person.PersonBuilder("John", "Alley").age(25).phone("123001").address("CHD").build();
		System.out.println(person1);
				 
		Person person2 = new Person.PersonBuilder("Amy", "Reacher").age(40).phone("5655").build();
		System.out.println(person2);
				 
		Person person3 = new Person.PersonBuilder("Mary", "Kal").build();
		System.out.println(person3);
	}
}

Output: Person: John, Alley, 25, 123001, CHD
Person: Amy, Reacher, 40, 5655, null
Person: Mary, Kal, 0, null, null

Here we are creating a Builder class that is PersonBuilder class. The PersonBuilder has a constructor that takes mandatory fields and optional fields can set by Setter methods. Each Setter returns the object after set the attribute.

Advantages of Builder Pattern

1. It provides design flexibility and code is more maintainable. The parameters of constructors are reduced as compared to other patterns.

2. Now there is no need to pass in null for optional parameters to the constructor.

3. It maintains the immutability of the object.

4. Object is always instantiated in a complete state

Disadvantages of Builder Pattern

1. Though the Builder pattern provides flexibility, it increases the number of lines of code because we write the code in the Builder class also.

2. We have to create a BuilderClass for each different type of Product

Leave a Comment