/**
* Example of an immutable pojo with a built-in builder. (getters left out for brevity)
* Admittedly most of the ugliness comes from the syntactic cruft of Java's way of doing closures
* and the lack of method aliases. Scala translation is here: http://pastebin.com/TASbJC5y
* I think this kind of builder could be automatically generated by a compile-time tool - for
* my next trick I'll write one.
* @author twitter.com/benhardy
*/
public final class PersonFeatures {
public final int userId;
public final int age;
public final int children;
public final int dogs;
private PersonFeatures(int userId, int age, int children, int dogs) {
this.userId = userId;
this.age = age;
this.children = children;
this.dogs = dogs;
}
// give each stage of the builder only one callable method,
// which returns the next stage
public interface BuilderUserIdSpec {
public BuilderAgeSpec userId(int v);
}
public interface BuilderAgeSpec {
public BuilderChildrenSpec age(int v);
}
public interface BuilderChildrenSpec {
public BuilderDogsSpec children(int v);
}
public interface BuilderDogsSpec {
public BuilderFinal dogs(int v);
}
public interface BuilderFinal {
public PersonFeatures build();
}
/* the builder method returns its first stage which allows you to set userId, and so on */
public static BuilderUserIdSpec builder() {
return new BuilderUserIdSpec() {
@Override public BuilderAgeSpec userId(final int _userId) {
return new BuilderAgeSpec() {
@Override public BuilderChildrenSpec age(final int _age) {
return new BuilderChildrenSpec() {
@Override public BuilderDogsSpec children(final int _children) {
return new BuilderDogsSpec() {
public BuilderFinal dogs(final int _dogs) {
return new BuilderFinal() {
@Override public PersonFeatures build() {
return new PersonFeatures(_userId, _age, _children, _dogs);
}
};
}
};
}
};
}
};
}
};
}
/**
* example usage. pretty obvious what is going on. only one way to do it. IDE will help.
*/
public static void main(String[]args) {
PersonFeatures person = PersonFeatures.builder().userId(4437).age(22).children(0).dogs(1).build();
}
}