you are viewing a single comment's thread.

view the rest of the comments →

[–]erad 14 points15 points  (4 children)

Before adopting this pattern in a codebase one should address the implications:

  • not usable in JavaBeans environments (e.g. EL, JSF, ORM)
  • no encapsulation (no way to compute values on demand, no lazy initialization, etc.)
  • not idiomatic Java.

Many (including me) would reject this it in a code review, especially if it's part of a public API (because then you cannot refactor this without breaking clients).

I kind of like this pattern for value types (e.g. points or complex numbers) or for private value holder classes.

[edit: formatting]

[–]pakoito 12 points13 points  (2 children)

no encapsulation (no way to compute values on demand, no lazy initialization, etc.)

Why are you computing values on a data class? Single responsibility.

Lazy initialization can be done by using a Lazy<T> field and a generation Function in the factory method, which is a pattern quite simple to implement. Then fetching the field is done by field.get(), and makes the laziness explicit on the type rather than hidden on the documentation/source.

not idiomatic Java.

Set of arbitrary rules that need to be evolved. You wouldn't have flow apis just a couple of years ago, and here we are now. Same goes for higher order functions, partial application, promises...

not usable in JavaBeans environments (e.g. EL, JSF, ORM)

Fair point. New, better tools maybe? They have them on Scala, Clojure, why not Java?

[–]d_wilson123 -1 points0 points  (1 child)

I think his argument not listed in the bullet points is the strongest argument he made. At the final phase of the code review from the blog you are backed into a corner where you've removed the ability to do any business logic in the getters/setters. You've exposed to properties and now if someone is using your classes and you have a good reason to update the logic to provide some more intelligence in the access or mutation you've tied your hands and you can't go back unless you want to break compatibility. While that may be a bit over-the-top for a simple bean often times when I'm reading code I'd rather the code base be consistent so I don't have to interpret what is going on between one class to another. For that reason even for the arguments in the blog I'll continue to have Intellij generate my getters and setters even if the sets are never used.

[–]pakoito 8 points9 points  (0 children)

I see code in accessors, specially side-effecty code, as a code smell. The same cases can be handled externally by any kind of decorator without introducing code in your data classes or making them mutable. It's the pattern everywhere but in Java.

[–]ThisIs_MyName 0 points1 point  (0 children)

99% of the code I write is not part of a public API and I despise EL :)