3 ms·
Honestly immutable data classes that are created via builders is a must have in Java.
by bognition 9y ago
Honestly immutable data classes that are created via builders is a must have in Java.
- eropple 9y agoIs there something that a builder gets you that Kotlin-style data classes doesn't?
- Matthias247 9y agoBuilders can set multiple fields of the data class at once, e.g. from a single builder parameter. They also can perform error checking whether the thing that the user actually wanted to build is consistent before returning a data class. There might be multiple fields in a class where the value of one field restricts possible values of another one. These are already some reasons why you want users to create objects through builders instead of initializing them directly. Another thing that builders provide is interface isolation: If your data class is only interpreted by your own libraries code you can modify it's (package-private) content as you like and require. The builder can evolve (and fill in additional fields as needed), and your code which consumes the built data class can evolve without breaking a user contract. Just the builder API needs to be stable (or backward compatible). With data classes this wouldn't work that easy, since you require the user to specify more parameters directly.
- cle 9y agoOne thing I love about builders, besides the sibling replies, is that builders force users to explicitly name the arguments. Passing args to a constructor/method/whatever with implicit argument ordering can be error-prone in certain situations (multiple adjacent args with the same type). c = Class(firstName, lastname) // are these passed in the right order? c = Class(lastName=firstName, firstName=lastName) // obviously incorrect Especially when you're using other magic like auto-generating constructors based on fields (as with Lombok)...then rearranging two String fields can subtly break things with no compiler errors!
- lmm 9y agoNamed parameters for functions (including constructors) are a good idea - better to build them in as a general case rather than making people read a lot more code to have them in one specific case. Look at what Scala does.
- emidln 9y agoMake fields public final and your constructor is your "builder".
- positr0n 9y agoThose two patterns aren't the same. You can pass around a half constructed builder but you can't pass around a half constructed public final object like you described.
- dtech 9y agoYou can in most modern or functional languages, by currying/partial evaluation/binding. It's rare for data classes. In scala: case class Foo(a: Int, b: String) val halfBuilt: String => Foo = Foo(1, _) val foo = halfBuilt("foo")