I am having trouble evaluating an implementation of the builder pattern I just came up with.
The context is an API library, so I am trying not to expose any implementations in order to have a stable interface while being able to change implementations later.
My thinking is that even though there is a reference to the implementation in the interface's file, the interface and the implementation are not actually coupled because
In effect, a static nested class is behaviorally a top-level class...
The benefit of this design is that clients can call
Person person = new Person.Builder().age(20).firstName("John")
.lastName("Doe").build();
without the need for a dedicated Factory type class.
Am I missing something or is this a valid design decision?
Person.java
package net.mhi.rd;
public interface Person {
int getAge();
String getFirstName();
String getLastName();
public static class Builder {
int age;
String firstName;
String lastName;
public Builder age(int age) {
this.age = age;
return this;
}
public Builder firstName(String firstName) {
this.firstName = firstName;
return this;
}
public Builder lastName(String lastName) {
this.lastName = lastName;
return this;
}
public Person build() {
return new PersonImpl(this);
}
}
}
PersonImpl.java
package net.mhi.rd;
class PersonImpl implements Person {
private final int age;
private final String firstName;
private final String lastName;
PersonImpl(Person.Builder builder) {
this.age = builder.age;
this.firstName = builder.firstName;
this.lastName = builder.lastName;
}
@Override
public int getAge() {
return age;
}
@Override
public String getFirstName() {
return firstName;
}
@Override
public String getLastName() {
return lastName;
}
}