@Target(value=TYPE) @Retention(value=SOURCE) public @interface FreeBuilder
Given an abstract class X and a set of abstract getter methods, the @FreeBuilder annotation processor will generate a builder class X_Builder, for use as a supertype of a boilerplate X.Builder class, e.g.:
@FreeBuilder
public abstract class DataType {
public abstract int getPropertyA();
public abstract boolean isPropertyB();
public static class Builder extends DataType_Builder {}
public static Builder builder() {
return new Builder();
}
}
An implementation of the abstract class X will be constructed and returned by the builder's
build() method.
DataType value = DataType.builder()
.setPropertyA(11)
.setPropertyB(true)
.build();
To set defaults and perform validation, override the relevant methods on the builder, e.g.:
public static class Builder extends DataType_Builder {
// Set defaults in the constructor.
private Builder() {
setPropertyB(false);
}
// Perform single-property (argument) validation in the setter methods.
@Override public Builder setPropertyA(int propertyA) {
Preconditions.checkArgument(propertyA >= 0);
return super.setPropertyA(propertyA);
}
// Perform cross-property (state) validation in the build method.
@Override public DataType build() {
DataType result = super.build(); // Ensures all properties are set
Preconditions.checkState(result.getPropertyA() <= 10 || result.isPropertyB(),
"Property A can only exceed 10 if property B is set");
return result;
}
}
Effective Java (ISBN 978-0321356680) recommends the Builder pattern when designing classes whose constructors or static factories would have more than a handful of parameters...say, four or more. But keep in mind that you may want to add parameters in the future....it's often better to start with a builder in the first place.
We follow most of the recommendations of Effective Java, except that we do not reqire all required parameters be passed to the Builder's constructor. This allows greater flexibility in use, plus increased readability from all parameters being named, at the cost of losing compile-time validation.
Copyright © 2015 Google, Inc.. All rights reserved.