Creational Design Pattern - Builder
The builder pattern is a creational design pattern that is used to create complex objects. When the number of instance fields of a class increases, the parameters of the constrcutor also increases. It is typically a bad practice to have too many parameters for a method (constructor is also a method). This amazing book Clean Code: A Handbook of Agile Software Craftsmanship
suggests that we should not pass more than three parameters because you can hardly remember them. With builder pattern, we can eliminate the ugly and long parameter list in constructor. Many Java frameworks used this technique such as the HttpSecurity
class in Spring Security and the HttpClient
in Java 11 HTTP Client API. Below is a simple example that demonstrates the builder pattern.
Builder Pattern Example #
First we create a User
class and a private contructor that accpets the UserBuilder
parameter. Therefore now client can only create the User
instance from the UserBuilder
class because the constructor is private.
class User
:
public class User {
private String username;
private int age;
private String sex;
private LocalDate dateOfBirth;
private User(UserBuilder builder) {
this.username = builder.username;
this.age = builder.age;
this.sex = builder.sex;
this.dateOfBirth = builder.dateOfBirth;
}
// getters
// toString
}
Next, we have to create the UserBuilder
class (static) inside the User such that the builder can access those private instance fields and of course create the User
object. The next step is to expose some public setters of UserBuilder
and return itself
to acheive the method chaining. Finally, expose a build()
method that will create and return the User
object to the client.
class UserBuilder
:
public static class UserBuilder {
private String username;
private int age;
private String sex;
private LocalDate dateOfBirth;
public UserBuilder setUsername(String username) {
this.username = username;
return this;
}
public UserBuilder setAge(int age) {
this.age = age;
return this;
}
public UserBuilder setSex(String sex) {
this.sex = sex;
return this;
}
public UserBuilder setDateOfBirth(LocalDate dateOfBirth) {
this.dateOfBirth = dateOfBirth;
return this;
}
public User build() {
User user = new User(this);
return user;
}
}
Try our UserBuilder
to create a User
object:
public class BuilderExample {
public static void main(String[] args) {
User user = new UserBuilder().setUsername("rick")
.setAge(12)
.setSex("M")
.setDateOfBirth(LocalDate.of(2009, 11, 12))
.build();
System.out.println(user);
}
}
Output:
User [username=rick, age=12, sex=M, dateOfBirth=2009-11-12]
- Previous: release 6 is not found in the system
- Next: Delegation vs. Forwarding