Builder Design Pattern in Java

UPDATED: 25 September 2021
The builder pattern, as the name suggest, we can use this pattern to build/construct complex objects. We should use this pattern when we want to construct same type of immutable objects with different sets of attributes.

Goal of Builder Design Pattern (https://en.wikipedia.org/wiki/Builder_pattern)
The goal of Builder design pattern is to separate the construction of a complex object from its representation so the same construction process can create different representations.
 
Now lets understand the builder design pattern with real world example. We all have Contact details in our mobile. Now lets construct Contact object with different sets of attributes.
 
For any Contact in our mobile, name is required data however email, mobile number, address, birthday are optional attributes. Now if we want to create immutable Contact object then constructor would look like as follow.

Source code (Contact.java)
/**
 * @author javaQuery
 * @date 2021-09-07
 * @Github: https://github.com/javaquery/Examples
 */
public Contact{
	private String name;
	private String email; // can be list of emails
	private String mobile; // can be list fo mobiles
	private String address;
	private Date birthday;

	public Contact(String name, String email, String mobile, String address, Date birthday){
		this.name = name;
		this.email = email; 
		this.mobile = mobile; 
		this.address = address;
		this.birthday = birthday;
	}	
}
In above example if you notice that even though email, mobile, etc... are optional to construct Contact object we have to pass null value for optional attributes. What other option we can think of is to create different constructor as per the requirements.
	public Contact(String name, String email){...}
	public Contact(String name, String mobile){...}
	public Contact(String name, String email, String mobile){...}
	public Contact(String name, String email, String mobile, String address){...}
	...
	...
Now what if we introduce another attribute anniversary? Contact object constructor would become more complex and hard to handle.
 
Builder pattern in action
Now lets use builder pattern to construct Contact object. We will take help of inner Builder class to construct the Contact object.

Source code (Contact.java)
import java.util.Date;

/**
 * @author javaQuery
 * @date 2021-09-21
 * @Github: https://github.com/javaquery/Examples
 */
public class Contact {
    private final String name;
    private final String email; // can be list of emails
    private final String mobile; // can be list fo mobiles
    private final String address;
    private final Date birthday;

    public Contact(Builder builder) {
        this.name = builder.name;
        this.email = builder.email;
        this.mobile = builder.mobile;
        this.address = builder.address;
        this.birthday = builder.birthday;
    }

    public String getName() {
        return name;
    }

    public String getEmail() {
        return email;
    }

    public String getMobile() {
        return mobile;
    }

    public String getAddress() {
        return address;
    }

    public Date getBirthday() {
        return birthday;
    }

    @Override
    public String toString() {
        return "Contact{" +
                "name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", mobile='" + mobile + '\'' +
                ", address='" + address + '\'' +
                ", birthday=" + birthday +
                '}';
    }

    public static class Builder{
        private final String name;
        private String email; // can be list of emails
        private String mobile; // can be list fo mobiles
        private String address;
        private Date birthday;

        public Builder(String name) {
            this.name = name;
        }

        public Builder email(String email){
            this.email = email;
            return this;
        }

        public Builder mobile(String mobile){
            this.mobile = mobile;
            return this;
        }

        public Builder address(String address){
            this.address = address;
            return this;
        }

        public Builder birthday(Date birthday){
            this.birthday = birthday;
            return this;
        }

        public Contact build(){
            return new Contact(this);
        }
    }
}
  
Source code (BuilderMain.java)
Using Builder class to construct the Contact object.
import java.util.Date;

public class BuilderMain {
    public static void main(String[] args) {
        Contact contactVicky = new Contact.Builder("Vicky")
                .email("vicky.thakor@javaquery.com")
                .build();
        System.out.println(contactVicky);

        Contact contactKrupa = new Contact.Builder("Krupa")
                .birthday(new Date())
                .build();
        System.out.println(contactKrupa);
    }
}

Builder pattern in JDK
java.lang.StringBuilder and java.lang.StringBuffer are widely known class which uses Builder Design Pattern. Using method append(....) you can construct the final object as per your requirements.
 
 
 

0 comments :