The Builder design pattern provides a simple way to construct complex objects using a step by step approach.
A builder class separates the construction of a complex object from its representation so that the same construction process can create different representations.
Advantages of Builder Pattern
- Builder pattern also helps minimizing the number of parameters in constructor are provides highly readable method calls.
- It encapsulates the logic of creating a complex object.
- It allows us to create a complex object step by step.
- Always fully constructed object will be available to client. rather than returning an incomplete object even if developer has not set all member fields.
- Easy to maintain if number of fields required to create object is more.
When we should use Builder Pattern
- When we needs different representations for the objects that are being built. Builder class provides a way to configure an object before creating it.
- The algorithm of creating a complex object is independent from the parts that actually compose the complex object.
- Once an object is fully created, you don't want to change it’s state.
Implementation of Builder Design Pattern
- We will create an Employee class containing employee information and a static nested class called EmployeeBuilder inside the Employee class whose object will be build Employee objects.
- Employee class must provide only public getter functions not setter function to ensure that employee object is immutable form outside.
- EmployeeBuilder class will have same set of fields as Employee class.
- EmployeeBuilder class will expose public method for setting all optional fields of EmployeeBuilder class. All setter functions will return a reference to current builder object.
- build() method of EmployeeBuilder class will create a new instance of Employee object by passing it self as constructor parameter. Constructor will copy the fields from builder object to Employee object. Clients will call build() method once they finished setting fields of builder.
public class Employee { private final String name; // Required private final String department; // Optional private final int age; // Optional private final int salary ; // Optional private final String rank; // Optional private Employee(EmployeeBuilder builder) { this.name = builder.name; this.department = builder.department; this.age = builder.age; this.salary = builder.salary; this.rank = builder.rank; } // we will only provide public getters to ensure that // object is immutable public String getName() { return this.name; } public String getDepartment() { return this.department; } public int getAge() { return this.age; } public int getSalary() { return this.salary; } public String getRank() { return this.rank; } public static class EmployeeBuilder { private final String name; private String department; private int age; private int salary; private String rank; public EmployeeBuilder(String name) { this.name = name; } public EmployeeBuilder setDepartment(String department) { this.department = department; return this; } public EmployeeBuilder setAge(int age) { this.age = age; return this; } public EmployeeBuilder setSalary(int salary) { this.salary = salary; return this; } public EmployeeBuilder setRank(String rank) { this.rank = rank; return this; } //Return the constructed Employee object to client public Employee build() { return new Employee(this); } } @Override public String toString(){ return "Name : " + this.name + "\nDepartment : " + this.department + "\nAge : " + this.age + "\nSalary : " + this.salary + "\nRank : " + this.rank; } }BuilderPatternDemo.java
public class BuilderPatternDemo { public static void main(String[] args) { // creating Employee object by setting all fields Employee emp1 = new Employee.EmployeeBuilder("George") .setDepartment("Finance").setAge(35).setSalary(30000) .setRank("2").build(); System.out.println(emp1.toString() + "\n"); // creating Employee object by setting only 3 fields Employee emp2 = new Employee.EmployeeBuilder("Mark") .setDepartment("Finance").setAge(35).build(); System.out.println(emp2.toString() + "\n"); // creating Employee object by setting only 1 field Employee emp3 = new Employee.EmployeeBuilder("Andy").build(); System.out.println(emp3.toString() + "\n"); } }
Output
Name : George Department : Finance Age : 35 Salary : 30000 Rank : 2 Name : Mark Department : Finance Age : 35 Salary : 0 Rank : null Name : Andy Department : null Age : 0 Salary : 0 Rank : null
- It encapsulates the construction of complex object and allow it to be constructed step by step.
- Builder pattern often builds a Composite.
- It is a creational design pattern.
Related Topics