Hacker News new | ask | show | jobs
by owlish 3918 days ago
I used to be a fan of the Builder pattern (or Fluent Interface), but the ease of use for developers comes at the cost of no compile-time checking. Before, you just had to look up the constructor to see which parameters go where, with the benefit of type-checking. Now, you have to look up the Builder's methods to make sure you've filled in all required fields. The only case where I can actually advocate using Builders is when you have a mess of telescoping constructors.
4 comments

If you have this problem, the library you're using is incorrectly using the Builder pattern. All required parameters should be in the constructor of the builder. Then the other methods on the builder should be optional configuration. For instance on Android you often see a builder that takes a `Context` in the constructor because that's almost always required.
This is contrary to the OP's example, where he passes data and num to the constructor, which is how I've seen it used frequently. The Builder pattern is often recommended to "make code easier to read" and wouldn't be useful if many/most of those parameters were required.
You can have a type-safe fluent Builder, but it requires having one or more static nested classes with private constructors. The outer class will not have a build() method, but rather that method will live in one of the nested classes. You use the type system to control what parameters have already been set, and what parameters need to be set.

Obviously, this can apply to many sorts of fluent API. This is at least part of what Tony Morris is alluding to in his essay on API design [1].

[1] http://blog.tmorris.net/posts/understanding-practical-api-de...

> Now, you have to look up the Builder's methods to make sure you've filled in all required fields.

the builder should fail with a good error message if there are required fields you didn't supply to the builder.

This doesn't solve the problem where the parameters aren't checked at compile-time. Now, hopefully all your codepaths are tested so your builder doesn't throw exceptions in production.
If you have required parameters in a Builder, you're doing it wrong.