The morning after

Sunday, June 18, 2006

Rich domain models: Intro

This topic will be a quite controversial one in the Java community in the near future, if not already.

I'm not 100% sure myself what to think about it, but here goes:

When people talk about rich domain models they are referring to an object model in which the participating objects are not simply data holders but also carry a lot of business logic which would 'normally' go into a service. In the current JEE project landscape most developers make use of what is known as anemic domain models in which objects are simply there to carry data back and forth, mainly for usage by a persistence engine such as Hibernate.

Now this sure sounds interesting but some issues quickly come to mind, I'll discuss them here.

What's wrong with anemic domain models ?

In my personal opinion it is not that bad to treat your object model as plain data holders, most people currently work that way by making use of the JavaBean convention where each field member has getter and setter accessors.

The advantage here is that you can treat the object model as a sort of API, the service layer can then act as a coarse-grain abstraction providing an interface to the business use-cases. Since the objects themselves have no specific business logic they can be reused by different service layers (in most cases you'll never need to share an domain model between different service layers, but the project I currently work on will require this).

The problem is more on a conceptual level where the objects would better reflect the real world if they would actually have specific behavior and knowledge of business logic. Bear in mind that moving service logic into objects will require you to significantly think (!) about your design, more specifically you'll have to become an expert in the business domain as well as a skilled modeler, here's where your analytic skills come into play.

On the other hand what does it mean to have something like Basket.add(Dvd) ? Technically it is not the basket adding the DVD, it is a human putting the DVD into the basket .. What do we do with this ? Is this an example a corner case ?


Will I be merging my service layer with my persistence layer ?

Yes and no. Business logic will obviously be moved from the service layer but surely not all of it, you will still need a service layer, it'll just be more lightweight.

There's a catch though. A business domain model implementing business logic is fine as long as you are navigating over the domain model itself, remember we are working with POJO objects, there are by default no dependencies outside of the domain!

Now take the case where a specific business operation needs to count the number of objects in the datastore, you'll not want to pass this number as an argument into the operation but rather you'll want the method itself to discover this. When you have a reference to the datastore available somehow the problem will be solved, but we don't have such reference!
This problem could be overcome by making using of AOP and having dependencies to external resources such as a datastore injected for you, this is quite elegant and can easily be done by making use of the runtime AspectJ support in Spring AOP.

What will I gain ?

First of all your service layer will be more light-weight and the object model will more naturally encapsulate the system's behavior. This opens the door to several alternatives.

With Java 6 around the corner support for scripting will be added, these scripts will be able to access the domain model directly, having business logic executed without any additional effort, that's beautiful, no ? (I'm actually using Drools at the moment, they are definitely more readable and lighter when working with a rich domain model).

Secondly you'll be able to better express yourself, this quickly becomes clear when writing unit tests, these tests typically are easier to understand and have less dependencies to external resources.

More on this topic later...

2 Comments:

  • This post has been removed by a blog administrator.

    By Blogger Walter, at 4:46 AM  

  • Hi Wouter,
    I was thinking about rich domain models and it looks to me we should use the service layer only to make operations affecting more than one instance of the classes. So the service layer would be used only to load/save instances, call instance operations and to make queries and other database wide processing.
    I'm not sure, but it looks to me this way we could avoid any dependency in the domain model.

    Walter

    By Blogger Walter, at 4:48 AM  

Post a Comment

<< Home