So I did some complaining last week that the data binding in Play wanted the attributes of the bound object to be public. Seriously, public variables on objects make hanging a GOTO look like a minor offense (considering the fact that the goto is utterly without pretense, as objects represent a certain masquerade that is blown by publicizing internal state). Well, the responses on Twitter, from the Play were predictable: Java is just a broken language, just use Scala. My response was ‘put a label on the front ‘sucks with Java‘ and watch Play interest drop to Tapestry levels. I have some tolerance for Promotion (with a capital P) left, though tiny exposures to Donald Trump can burn up the reserve, but the idea of Java being too lame to be able to carry the brilliance that is Play is beyond silly. The argument was that Scala provides accessors for you (if that‘s our measure of its genius as a language, I‘m sure its acolytes will be loath to find out that Objective-C beat them to that base by half a decade at least). The fact is, Play is far from revolutionary. It‘s basically Rails‘ structure and a very simple set of just enough tools to get the basic http landscape done.
There is something revolutionary about Play though: it‘s the overall balance it strikes. Like Apple, Play is a rather complete offering (when combined withSBT). While it‘s not perfect, so far my experience with it makes me NEVER want to go back to Tomcat, that‘s for sure. Why? Well, when you run Play, it works almost every time. The refreshes just work, almost all the time. And what a pleasure it is to have a build tool that can also run what it built. This part of Play is the part that is quite literally breathtaking at times. You get into a zone when using it that feels like oxygen therapy. I saw a cartoon today of coders sword fighting in the hall, upon being told to go back to work, blurting out ‘compiling…‘ Herein‘s the rub: turns out, the Scala compiler is the real reason that unit tests are so dreadfully slow in Play. So what it gives on the runtime side, it quickly takes away, and in a super sick and twister irony, for those of us who aren‘t even using Scala, we are accepting a 10x slower compile time. (See my prior post.)
All that said, I would still use Play again. I noticed in going through the docs again today that I can register my own binders. Why can‘t I register a binder at the form level? (Play is using Spring underneath, wondering why I can‘t just have something that gets handed the inputs as strings from the request and returns the object. Probably the answer is that it‘s all tied into the lifecycle, as it is in JSF, but worth a look.) On the object level, I am going to try to make some IntelliJ Live Templates for easing the process of writing a binder for a type that uses that type‘s static Builder. Even if it takes me a little typing, it is absolutely worth it. One of the other obvious reasons is that the Builder also provides a pipelining mechanism for construction semantics. If you want to take the mild contracts approach to coding, do your checking in the constructor that decamps the provided values from the Builder, throwing your various exceptions of choice (IllegalArgument/IllegalState).
Here is the biggest thing I started to realize the other day: I need to make my Play project, then strip out most of the core logic of the app into another project. Think about it: if that other project is pure Java, I can write TDD style at light speed, and then just switch over to the Play project to integrate it. Yesterday I was working on some logic for adding mapped members of another class after coming out of a creation form. I fell into the bad approach of writing the code and trying different things in the form. I popped out and went to a unit test and resolved it quite quickly, but the unit tests were slow.
Yet, after some initial looking, this seems to be one area where eclipse has IntelliJ beat. In eclipse, I can make one big git project with sub projects in subdirectories, and one compiling to a war and the others to a jar. In IntelliJ, it seems it wants me still to generate the idea files from the Play project and then add a ‘module.‘ Have not really figured out how to make this work yet. But this is no doubt the direction.
One last thing: in using Morphia, the only thing I miss from Hibernate is the ease of Cascade. I knew how much I loved it when I was using Hibernate, now that it‘s gone, it feels pretty primitive to have to ask for specific updates to parts of the object graph. That said, when you think about it, there is not that much going on there: it‘s a pretty simple semantic translation of basic operations (save/load). Got me thinking about whether, if I tried to adapt the concept to Morphia, I would adopt it as is or change it. The problem with Cascade is it mixes model considerations and tactical runtime optimizations. Makes you feel dirty just thinking about it. Might be better to separate those. I don‘t like the idea of anything runtime being pasted on to the domain classes. Furthermore, since there are no joins in document databases, the whole idea of cascade is kind of different: we are not so much talking about a whole/part problem as more of a flow. Might make more sense to consider the notion of message-oriented notifications instead. For instance, even with cascade mechanisms, we are left to mind the two sides of relationships (though at the object level), so if we add a person to a group, and the person has a reference to the Group, it‘s our responsibility to plug that in, and mind it when/if it changes. In a notification scheme, we would be publishing a request for a User to join a Group. Once each side received it, and perhaps negotiated terms, the required updates to their own state would be their own business. (I wonder how the Reactive guys feel about MVC.. kind of fails the R litmus test, especially when considered alongside PAC, which is built on event interconnects….)