What I finally came up with is not strictly a builder but something I rather call an initializer. The initializer contains the initial state required by the target object. The state is accumulated within the initializer. Only when the state is complete can it be passed to the targets object’s constructor. Java’s type system prevents passing a initializer with an incomplete state to the target class’s constructor.

The basic technique is the same as for the Type-safe Builder Pattern in Scala: the phantom types TRUE and FALSE are used to keep track of the state. Only a complete state will result in a Initialiter instance which subsequently can be passed to Foo‘s constructor.

Actions

Information

10 responses

I wrote the same thing in Java, then decided that it didn’t readably scale up to 10 parameters or so, which is the case that Builder is actually a useful pattern for. X[FALSE, FALSE, FALSE, FALSE, FALSE..] is difficult to call readable.

[…] Type-safe Builder Pattern in Java « Michid’s Weblog – Recently I read this rather fascinating post about a Type-safe Builder Pattern in Scala. When Heinz Kabutz mentioned the builder pattern in his latest issues of the The Java Specialists’ Newsletter I decided to try to come up with a type safe version for Java. […]

True, but you see it in the implementation and in the IDE’s prompting while you’re writing the use. And if you work under a coding standard that prefers naming subexpressions to writing long lines (even with wrapping) the lack of type inference in Java makes the pain return.

Hi! Actually, in Java you can use a much simpler approach to get type-safe Builder (although Rafael’s approach looks nice it’s not really required in such case). You just declare a Builder’s constructor, that takes all required parameters. Then you set all optionals via chained Builder method calls.

If there are more required params, overloaded Builder constructor may help. In most complex cases (10 or more req. params), you can put static factory methods to Builder.

So phantom types are cool, but in this case there is better (and more KISSy) solution IMHO.