Must you always use a rich domain?

Ask a Java developer in my neck of the woods to create a web application (of the usual "shovel some data from Oracle to HTML" variety) and s/he will probably come up with an instant architecture. Some sort of MVC => Spring => domain layer => Hibernate => database. Blueprint done, let's go write some code now.

What can possibly be wrong with this? The Spring => domain layer => Hibernate part. There are many simple web applications where a full-blown domain persisted by a full-blown object-relational mapper and wired together by a full-blown dependency injection framework with aspect-oriented programming features provides no value, but has a big price in terms of complexity, scalability and long-term maintenance. And every complex web application that I have seen so far had some areas where rich domain backed by ORM was not the best way to go, either.

A classical example is a web application that is all about searching and viewing some stuff, stored in a relational database. Usually, there is some data manipulation involved, but it's all CRUD. Whenever this application has a domain, it is inevitably an anemic one - in other words, there are getters and setters, maybe some data validation logic, and not much interesting behavior. Unfortunately, there seems to be a blind spot where every greenfield application must have a domain layer complete with DI and ORM. Surely, all this byte-code manipulation voodoo and angled-brackety declarative configuration goodness must have some cost to it? And it does!

First, there is always a performance penalty to pay. The moment you decide to go with a full-scale ORM, you probably increase production hardware costs by at least 50%. I don't have any hard numbers to back this with, so this is just a subjective opinion of someone in the trenches who is considered "a performance dude" in ThoughtWorks. In the world where developer time is expensive and hardware is not, this is a great tradeoff, as long as you save developer time.

But this is the catch. When there is no rich domain, no need for distributed transaction management, or advanced caching strategies or other things of this nature, you may not be saving anything - quite the contrary. You just end up writing more code to wire all those decoupled layers together, running longer builds (a much bigger productivity killer than most people realize), having to deal with more interesting problems, reading much larger and less informative exception stack traces, and generally working harder than necessary.

And then there is the maintenance cost. Conceptual complexity, all this cool voodoo, is hard on production support. It creates more situations that regular support people can't cope with on their own and have to escalate to platform experts.

One major selling point for Hibernate is that it eliminates a lot of boilerplate JDBC code to map data from rows to objects. One day, Sun will hopefully bake something like LINQ into Java and the boilerplate data mapping issue will be gone for good. Until then, there are libraries out there that do just this (IBATIS comes to mind) at a tiny fraction of Spring+Hibernate complexity cost.

Now, there are people who take this to the other extreme, and just mix SQL with markup. Although it's a great design for a "Hello, World"-type system, I'm not radical enough to advocate this for anything bigger.

So, next time you start writing an application that is 90% data display and 10% CRUD manipulation -- if something like Rails or Django is not an option -- please at least think about MVC => service => hand-coded SQL option.



At February 7, 2009 at 2:46 AM , OpenID jchyip said...

This actually sounds like something worth getting better numbers on.

At February 7, 2009 at 5:14 PM , Blogger David Dossot said...

Indeed. A colleague of mine decided to address part of the ORM performance discussion a while ago.

This said, Alexey, I fully agree with you. Because they can map data to objects, people tend to think they *have to*. This drives me nuts!


At February 7, 2009 at 6:18 PM , Blogger Alexey Verkhovsky said...

I don't think it's possible to put hard numbers on the cost of conceptual complexity. Especially long-term maintainability costs. But I have plenty of anecdotal experience that they are non-trivial.

At February 8, 2009 at 5:58 AM , Blogger Chris said...

Another way of going, instead of using Hibernate on simple web apps might be to use something like CouchDB or DB4O, both seem lightweight and much easier to use then Hibernate.

At February 8, 2009 at 1:26 PM , Blogger Alexey Verkhovsky said...

Object- or document- oriented databases are a pretty big paradigm shift. So far, I only had one negative experience with this stuff, but that was largely dueto immature implementation of the OODB technology we used, and my own stupidity. Who would've thought that an object database has a schema (?!) and requires versioned migrations (?!!!) :)

I'd love to try doing a CouchDB-backed app one day.


Post a Comment

Subscribe to Post Comments [Atom]

<< Home