Builder pattern helps us create immutable class instances. Instances that you set their state once and don’t change it for the rest of the program. By not having setters and only initialize fields through constructors the object is immutable.
public User (String firstName, String lastName, int age, String phone){ } public User (String firstName, String lastName, String phone, String address){ } public User (String firstName, String lastName, int age){ } public User (String firstName, String lastName){ }
The problem is with this approach is that the number constructors to create can be too many to maintain properly. If we add setters we will lose immutability. This is where the Builder pattern comes into the picture.
How to implement:
public class User { private String firstName; private String lastName; private int age; private String phone; private User(UserBuilder builder) { this.firstName = builder.firstName; this.lastName = builder.lastName; this.age = builder.age; this.phone = builder.phone; } //---- all getters no setters public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public int getAge() { return age; } public String getPhone() { return phone; } public static class UserBuilder { private String firstName; private String lastName; private int age; private String phone; private UserBuilder() {} public static UserBuilder standard() { return new UserBuilder(); } public static User defaultClient() { return new UserBuilder().build(); } public UserBuilder firstName(String firstName) { this.firstName = firstName; return this; } public UserBuilder lastName(String lastName) { this.lastName = lastName; return this; } public UserBuilder age(int age) { this.age = age; return this; } public UserBuilder phone(String phone) { this.phone = phone; return this; } public User build() { User user = new User(this); validateUserObject(user); return user; } // validate user object private void validateUserObject(User user) { } } }
Main class
public class BuilderMain { public static void main(String[] args) { User user = UserBuilder.standard() .age(12) .phone("3101234567") .firstName("Folau") .lastName("Kaveinga") .build(); System.out.println(ObjectUtils.toJson(user)); } }
Something developers need to keep track of is that when adding a new field to the immutable class it needs to be added to the builder as well.
Advantages
Disadvantages