Writing Java builders like a pro
This is my preferred approach to Java builders. To illustrate, here's a class representing an HTTP cookie.
public final class Cookie {
public static final class Builder {
private Option<String> name = Option.none();
private Option<String> value = Option.none();
private Option<Instant> expires = Option.none();
public Builder setName(String name) {
this.name = Option.some(name);
return this;
}
public Builder setValue(String value) {
this.value = Option.some(value);
return this;
}
public Builder setExpires(Instant expires) {
this.expires = Option.some(expires);
return this;
}
public Cookie build() {
return new Cookie(this);
}
}
private final String name;
private final String value;
private final Option<Instant> expires;
private Cookie(Builder builder) {
name = builder.name.getOrThrow("No name was set.");
value = builder.value.getOrThrow("No value was set.");
expires = builder.expires;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
public Option<Instant> getExpires() {
return expires;
}
}
I like this because
- The
Cookie
class is immutable. Not just "externally immutable" in the sense of not exposing mutators, but internally immutable as well. - There are no "nullable" fields.
Option
is the more type-safe alternative - The user will get a descriptive error if they forget to set a required field. And we accomplish this without needing a bunch of conditional blocks.