Implement the builder pattern prior to Java 8 has lots of tedious, nearly duplicated code; the builder itself is typically boilerplate code. Some duplicate code detectors co
I have recently tried to revisit the builder pattern in Java 8, and I am currently using the following approach:
public class Person {
static public Person create(Consumer buildingFunction) {
return new Person().build(buildingFunction);
}
private String name;
private int age;
public String getName() {
return name;
}
public int getAge() {
return age;
}
private Person() {
}
private Person build(Consumer buildingFunction) {
buildingFunction.accept(new PersonBuilder() {
@Override
public PersonBuilder withName(String name) {
Person.this.name = name;
return this;
}
@Override
public PersonBuilder withAge(int age) {
Person.this.age = age;
return this;
}
});
if (name == null || name.isEmpty()) {
throw new IllegalStateException("the name must not be null or empty");
}
if (age <= 0) {
throw new IllegalStateException("the age must be > 0");
}
// check other invariants
return this;
}
}
public interface PersonBuilder {
PersonBuilder withName(String name);
PersonBuilder withAge(int age);
}
Usage:
var person = Person.create(
personBuilder -> personBuilder.withName("John Smith").withAge(43)
);
Advantages:
Possible drawbacks:
Possible alternative:
We can setup a constructor with a building function, as follows:
public class Person {
static public Person create(Consumer buildingFunction) {
return new Person(buildingFunction);
}
private String name;
private int age;
public String getName() {
return name;
}
public int getAge() {
return age;
}
private Person(Consumer buildingFunction) {
buildingFunction.accept(new PersonBuilder() {
@Override
public PersonBuilder withName(String name) {
Person.this.name = name;
return this;
}
@Override
public PersonBuilder withAge(int age) {
Person.this.age = age;
return this;
}
});
if (name == null || name.isEmpty()) {
throw new IllegalStateException("the name must not be null or empty");
}
if (age <= 0) {
throw new IllegalStateException("the age must be > 0");
}
// check other invariants
}
}