I showed off a hand-rolled example Java builder pattern today. It has some benefits over existing builder solutions, but is more work than I like:
- All parts of the builder are immutable; you can pass a partially built object for another object to complete (I'm looking at you, Lombok)
- It's syntactically complete; that is, code won't compile without providing all arguments for the thing to build
- It's easy to generalize; in fact, I'm thinking about an annotation processor to generate it for you (but not there quite yet)
@EqualsAndHashCode
@ToString
public final class CartesianPoint {
public final int x;
public final int y;
public static Builder builder() {
return new Builder();
}
private CartesianPoint(final int x, final int y) {
this.x = x;
this.y = y;
}
public static final class Builder {
public WithX x(final int x) {
return new WithX(x);
}
@RequiredArgsConstructor
public static final class WithX {
private final int x;
public WithY y(final int y) {
return new WithY(y);
}
@RequiredArgsConstructor
public final class WithY {
private final int y;
public CartesianPoint build() {
return new CartesianPoint(x, y);
}
}
}
}
} That was a lot to say! Which is why most times you don't hand-roll builders. Usage is obvious:
@Test
public void shouldBuild() {
final CartesianPoint point = CartesianPoint.builder().
x(1).
y(2).
build();
assertThat(point.x).isEqualTo(1)
assertThat(point.y).isEqualTo(2);
} Adding caching for equivalent values is not hard:
public static final class Builder {
private static final ConcurrentMap
cache = new ConcurrentHashMap<>();
public WithX x(final int x) {
return new WithX(x);
}
@RequiredArgsConstructor
public static final class WithX {
private final int x;
public WithY y(final int y) {
return new WithY(y);
}
@RequiredArgsConstructor
public final class WithY {
private final int y;
public CartesianPoint build() {
final CartesianPoint point = new CartesianPoint(x, y);
final CartesianPoint cached = cache.
putIfAbsent(point, point);
return null == cached ? point : cached;
}
}
}
}
No comments:
Post a Comment