The Faceted Builder Pattern is a sub pattern of the builder pattern. Its purpose is to clarify the construction of a complex object “fluently.” Let’s say we want to build a User object with its personal data (personal info, address, education and education). This pattern enables us to have this:
User user = new UserBuilder()
.called()
.firstname("Matthew")
.middlename("Fred")
.lastname("Dupont")
.lives()
.address("123 rue de la pomme")
.city("Montauban")
.postalcode(42331)
.state("Occitanie")
.country("France")
.studied()
.elementary("Ecole Municipal de Paul Laffort")
.middleschool("College Pourvoira")
.highschool("Le Bac de Demain")
.university("Polytechnique")
.build();
The idea is to define a UserBuilder class that will have three subclasses: UserInfoBuilder, UserAddressBuilder, UserEducationBuilder:
class User {
// all fields here...
private String firstname;
private String lastname;
...
User(UserBuilder builder) {
this.firstname = builder.firstname();
...
}
}
class UserBuilder {
public UserInfoBuilder called() { // return info builder to set info
...
}
public UserAddressBuilder lives() { // same for address
...
}
public UserEducationBuilder studied() { // same for education
...
}
public User build() {
return new User(this);
}
}
// since UserInfoBuilder extends UserBuilder, we can call lives()
// or studied() once we are done setting up the personal info
class UserInfoBuilder extends UserBuilder {
private String firstname;
...
public UserInfoBuilder firstname(String firstname) {
this.firstname = firstname;
}
public UserInfoBuilder middlename(String ...) // same
public UserInfoBuilder lastname(String ...) // same
}
class UserAddressBuilder extends UserBuilder {
private String address;
public UserAddressBuilder address(String address) {
this.address = address;
}
public UserAddressBuilder city(...) // same
public UserAddressBuilder postalcode(...) // same
...
}
class UserEducationBuilder extends UserBuilder {
...
public UserEducationBuilder elementary(...) {
...
}
...
}
That’s all!