Builder Design Pattern in Java
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.
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.