We are commonly taught to create objects using the JavaBean pattern, where for every variable there is a corresponding getter and setter, or by passing in attributes to the object’s constructor on creation. For example:
Employee emp = new Employee("name", "some address", "city", "state", employee_number, salary, department, … more arguments);
Not only is this not ideal to read, you must remember to pass the values in the correct order. Even type safety will not help you if, for example, you interchange the city and state arguments. Also, if the Employee class has only two mandatory fields (name and employee number) the developer must add null entries to fields they do not want to set at creation time.This method also violates the Open/Closed principle (PDF link) where classes should be open for extension but closed for modification – thus to increase functionality, add new code (via abstraction), rather than changing old code.Using a Builder Pattern allows you create the same object in the following way:
Employee emp = new Employee.Builder("Rich Sharpe", 32) .address("1 Java Way") .city("Javaland") .salary(12000.00) .department(AccountsDept) .build();
Not only is this more robust than the JavaBean pattern or the long unwieldy constructor, but the creation of this object is now far more elegant to read.Here is the partial Employee class:
public class Employee { private String name; private String address; private long employee_number; private double salary; public static class Builder { private String name; private String address; private long employee_number; private double salary; public Builder(String name, int employee_number){ this.employee_number = employee_number; this.name = name; } public Builder salary(double salary){ this.salary = salary; return this; } public Builder address(String address){ this.address = address; return this; } //Additional setters here... //Finally add the build method public Employee build(){ return new Employee(this); } } private Employee(Builder builder){ this.name = builder.name; this.address = builder.address; this.employee_number = builder.employee_number; this.salary = builder.salary; //Copy remaining data from Builder to Employee... }}
Create a static ‘builder’ class within your class and provide individual setter methods. Finally add a ‘build’ method that returns an instance of its class as a parameter to a private constructor of the class you wish to build.If a specific exception needs to be thrown, then the private Employee constructor and public build() methods can handle this (remember IllegalArgumentException and IllegalStateException do not have to be specifically declared in a throws clause).Usually this type of creation pattern is used when an object will not change during its life. I chose to create a User class as for this example as a huge benefit of this type of creation is that the object is immutable and therefore thread safe.Although a user may change some attributes; such as their last name if married or address when moving, these are so rare that it may be better to just delete the current object and create another as object creation is very inexpensive and one retains the benefits of an immutable object.
Leave a comment »