More on boilerplate and IoC

Java has lately been seriously annoying me in this regard. Why do I have to write getters/setters for beans? Why can’t we just have a property keyword instead that does it automatically? Why does everyone insist on using getters/setters in the first place rather than public fields anyway? What’s the point? Ah, yes, we need to be able to proxy the methods through cglib for Hibernate, or via Spring’s IoC/AOP stuff, so we can write “better” code with fewer dependencies.

For all Spring’s AOP wonder, for all its magic wiring of interfaces that make things harder to debug, for all that, what have we really gained?

Myth #1: “Your code is less coupled, which can only be good.”
Err, no it isn’t – it depends on Spring. If I wired it together using plain Java I’ve have fewer dependencies and no awkward XML that my IDE doesn’t understand semantically and can’t type-check. It’s true that Spring encourages you to introduce fewer couplings, but a good Java coder or architect will do that anyway. I hope you don’t entrust the design of your app’s top-level components and how they should talk to each other to someone who’s a bad coder.

Myth #2: “It makes the dependency injection easier!”
Well, yes and no. You can use the clever autowiring. But then you run the risk of maintainers not understanding which things are wired together and how it all works. The Spring manual itself admits:

Autowiring is more magical than explicit wiring. Although, as noted in the above table, Spring is careful to avoid guessing in case of ambiguity which might have unexpected results, the relationships between your Spring-managed objects is no longer explicitly documented.

Well, great: If I’m maintaining someone else’s project and need to bump the Spring version number, is that magic good? What if the behaviour changes due to a bug/fix, and it breaks? How do I even know what the relationship should have been?

To quote the Spring manual again:

In most cases, the answer to the question of whether you should use auto-wiring is definitely “No!” Auto-wiring can save you time in small applications, but in many cases, it leads to bad practices and is inflexible in large applications.

So if we ditch that, what does Spring IoC buy us? It works out the ordering for dependency creation and injection. My IDE does that trivially – shuffle things about ’til the squiggly red lines go away. This isn’t really a hard problem that needs solving with special tools, IMHO. If you do it in Java you then have the advantage that you’ll know what the order will be just by reading the easy-to-understand code. Look, you can even set breakpoints during your context initialisation and everything!

Myth #3: “Only IoC enables you to update the configuration without recompiling.”
So does Java. If you need to do that, put the configuration in a properties file. Which is probably what you’d be doing anyway, with Spring’s PropertyPlaceholderConfigurer. Even ignoring that, who actually does this on live systems? Particularly for webapps, you’ll want to build a WAR. You’ll have some kind of build system for that, right? Are you really going to unpack the existing WAR and edit the XML? Or are you going to edit the XML and run the build script? If you do the former, how do you know your newly edited context will work? You have unit tests for that, right? Which get executed when you run the build scripts, yes? So, why is updating a Java file considered to be such a big deal?

The worst aspect of all this, alluded to in the rest of this post, is that we write mountains of IoC configuration in XML, of all things. To be able to maintain such a project, you need to be able to grok the XML. And Point #3 on w3c.org’s XML synopsis is “XML is text, but isn’t meant to be read”. XML should be parsed by machines. Java should be parsed by humans first, and machines second (at least if you want your code to be maintainable). Spring configuration appears to be sufficiently hard to read that people are now pushing Spring config using domain-specific XML. Great – I now need to learn an entire new grammar to be able to configure each niche library/technology/product! Someone tell me again why everyone is replacing trivial Java with nasty XML full of magic?

Myth #4: “You can replace Hibernate with something else, and your API consumer doesn’t have to change anything, because it’s all just interfaces!”
Err, yes. What’s to stop you writing against your interfaces and making a factory class for your DAOs which hides the Hibernate bits as much as possible? Why would you need IoC for that? Besides, has anyone ever actually done this? If you can find a complex app where replacing the Hibernate layer with some other technology would involve no DAO interface changes, I’ll eat my hat. Hibernate and your DAO interfaces are an abstraction. Abstractions leak. Lazy-loading, in particular, leaks like a sieve, all the way across your nice tiered app. Ah, implement an OpenSessionInView filter, I hear you say. Which promptly leaks in three-tier designs where your domain objects are pulled across RMI or whatever.

Oh, why do we torture ourselves so?

2 thoughts on “More on boilerplate and IoC”

  1. I disagree with you wrt the public fields issue. There are many reasons to encapsulate access to some data field other than dynamic proxying and other stuff. Data hiding can really help if your application matures and changes.

    That said I agree that writing setters and getters is moronic and that the language should provide ways to easily create them //when needed// without it being visible to calling code, so that we can change something like:

    property long count;

    to

    property long count set { …. }

    while all the time using the property itself in code like
    c.count = c.count + 1;

    This would at least fix the heaps of boilerplate crap present in most POJO classes.

    But even more important than preventing the zillion of stupid “getters and setters” is having this in place to create //property references// from code.

    Lots of frameworks need to refer to objects and properties of objects from within code. Take for instance Hibernate; when issuing a query you can easily create a class reference using something like “User.class”. But creating a criteria query on the user’s ‘name’ property must be done by coding the “name” field as a string:
    c.add( Restrictions.eq(“name”, “Jalvingh”));

    This makes most frameworks very fragile wrt refactoring and data changes, and it makes the reference invisible to most tools making change impact analysis hard.

    Having properties as first-class elements in the language would make it possible to encode references to these properties which can then be checked at compile time by the compiler, and are visible to frameworks and IDE’s. For me this is the //real// value of properties syntax in Java.

    As far as your comments on the Spring framework go: I mostly agree. Although I really like IOC when it is used to remove framework and factory references from beans, I am not impressed by the Spring way of configuring things. This is where I partly disagree with myth #4: having beans that do not contain references to the factories for the dao implementations are worth having; it really cleans up the code and removes dependencies not worth having.

    Spring configuration is indeed a disaster. One gets a complete heap of “code” (in XML) that is invisible to any tooling. And this “code” forms a considerable amount of your application! I also dislike the many highly technical tricks needed to get stuff to work. If that much trickery is needed replacing Spring with something else might be very hard indeed.

    Something that also bothers me is that although it is easy to keep simple code clean from Spring dependencies internally this is not doable when using many of the Spring “enhancements”. Take for instance the Hibernate DAO layer encoded with Spring – it enforces your DAO’s to be derived from a Spring base class to handle declarative transaction management… Gross.

  2. Thanks for the comments. :)

    I appreciate there are many reasons to encapsulate things with getters/setters. I’m just railing against the most common use case. Tools should make 80% of your job easy and the remaining 20% possible. Java seems to fail somewhat on simple things like this.

    I completely agree on the benefit of first-class properties in Java for things like Hibernate (Wicket could also use this for PropertyModels and the like). I’d really, really like that and was saving a rant about it for another day. It would make usage of things like Hibernate and Wicket so much nicer.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>