Archive for October, 2007

User interfaces: the enemy of Domain Driven Design

I’m passionate about Domain Driven Design (DDD).  Like many experienced object modellers, I was practicing this long before Eric Evans coined that specific term, though I have sinced learned some useful  specific patterns from his book. To me, DDD is about two things: focussing on the business functionality rather than on the technical implementation; and focussing on building a good model of the business domain rather than  just on the specific immediate requirements.  Like many others, I perceived that the key to this was to model the domain as behaviourally-complete domain objects: to actively resist the tendency to separate business functionality from the persistent domain entities.

Over the years I’ve been involved in a number of significant projects where the team started out with the intention of doing what we now call DDD.  I’ve seen some very good examples of object modelling, often just done on paper, sometimes even implemented as code.  But what is both striking and depressing is to observe how much the initial domain model has been eroded and/or corrupted by the time the first application is delivered.  Thereafter it’s a vicious circle:  the emasculated domain model delivers less and less of the required functionality, so more and more is built into layers on top of the model, and so on.  I’ve often heard the remark this this shows that a religiously-pure approach to object modelling just doesn’t work in the real world of business.  I never bought that argument.

The research that led to the naked objects pattern was motivated, in large part, by this sad state of affairs.  The naked objects pattern arose from the realisation that it was possible to convert this vicious circle into a virtuous circle:

If you are committed to designing behaviourally-complete domain objects, then the user interface need be nothing more than a direct reflection of the domain objects.  And if you make your user interface a direct reflection of the domain objects, then it will both force and help you to make the domain objects behaviourally-complete.

I’ve many times written about the DSFA in Ireland, which is not only a poster-case for Naked Objects, but also one of the largest-scale examples of ‘pure’ DDD anywhere in the world.  How do I defend that claim?  Because if you talk to anyone at the DSFA who has any involvement in the new generation of systems, whether they are a user, a business sponsor, or from the Information Services Division, all they talk about is the domain model: what are the capabilities of the Customer object? How does the Payment object relate to the Entitlement objects?  Should a (payment) Book object know the BookRenewalCycle object that it falls within? This is not just because the domain model is visible and concrete, but because there is nothing else (in terms of business functionality) to talk about.  The domain model has survived right through to implementation.  As the DSFA now discusses the next phase of business solutions to be created within the new architecture, the language of the discussion is how to extend the domain model, not how to write new ‘applications’.

I’ve also many times said that it is possible to use Naked Objects to help you explore your domain model, even if your ultimate iwhat ntention is to deploy that domain model within a more conventional architecture. But I now feel the need to put a caveat in there: one based on real experience.  Yes, you can use Naked Objects to help you explore and prototype your domain model as a set of POJOs, and I believe you’ll end up with a better domain model than by trying to do it using UML diagrams on any other modelling methodology.  But, be warned, as soon as you then concede the idea of designing a user interface to sit on top of the domain model, and you will find the domain model starts to degrade.   Users no longer talk about the domain ‘objects’, they talk about ’screens’ instead.  The screens then start to acquire attributes from multiple objects, and the behaviours start to get associated with the screens rather than the objects, and before you know it the domain model is little better than a logical data model (or even a physical data model!). 

People often say to me:  ‘Doesn’t this just reflect the reality that users need to see views that cut across the domain objects?’  No.  At the DSFA we built huge applications using hundreds of domain classes all representing persistent entities.  I can think of only two instances in the whole system where we created domain object classes (containing some business logic) that were not persisted and, it could be argued, really represented either a view that spanned multiple objects, or a high-volume entry form that fed multiple objects.  The belief that views should be independent of objects is just a self-fulfilling prophecy.

I’ve suggested in the title, user interfaces can be the enemy of domain driven design, and doubtless for this I shall get castigated for pushing idea that favours systems developers at the expense of the user.  The usuability community has never liked the idea of Naked Objects.  They’ve been quick to point out the many small usability issues with the auto-generated Naked Objects user interfaces.  But, to use a biblical metaphor, I suggest that they are ‘choking on a gnat while swallowing a camel’. Yes there are hundreds of small ways in which the Naked Objects user interfaces can and should be improved.  But there are many higher-levelways in which those same user interfaces are actually more usable than many hand-crafted interfaces I’ve seen from so-called usability experts:  less modal, more empowering, and with a real sense of Norman et al called ‘direct engagement’.

My challenge to the usability community is to stop fighting the idea of generic user interfaces, and apply what they know to building better ones.

Richard Pawson

Naked Objects and AOP - Part 2

Last month I wrote about the potential synergy between Naked Objects and AOP.  Since then I’ve conducted my first crude experiments with Aspect and the AJDT plug-in for Eclipse.  (I found the latter remarkably straightforward to install and use).

 The first of my suggested uses for AOP within Naked Objects was to eliminate the need for adding resolve() and objectChanged() calls within your properties.  I managed to get this working, and I’ve posted the code below for anyone who’d like to try it out.

 (As I’ve made clear, I’m a complete beginner at AOP, so if anyone more experienced in that technology can see anything wrong with this code, or any improvements, please do post a comment.)

Richard

import org.aspectj.lang.reflect.MethodSignature;

import org.nakedobjects.applib.DomainObjectContainer;

 

public aspect ResolveAndObjectChanged {

 

// {{ Define the ContainerAwareObject interface and its methods

 

public interface ContainerAwareObject {}

 

private void ContainerAwareObject.objectChanged() {    container.objectChanged(this);

}

 

private void ContainerAwareObject.resolve(Object object) {

    container.resolve(object);

}

 

private DomainObjectContainer ContainerAwareObject.container;

 

// Naked Objects will inject a DomainObjectContainer here

public void ContainerAwareObject.setContainer(

    DomainObjectContainer container) {

    this.container = container;

}

// }}

 

// {{ Declare domain classes that should implement ContainerAwareObject

declare parents : projectname.dom.* implements ContainerAwareObject;

// }}

 

// {{ Define the objectChanged pointcut and advice

pointcut objectChanged(ContainerAwareObject target, Object objectBeingSet):execution(void ContainerAwareObject+.set*(..)) && target(target) && args(objectBeingSet);

 

after(ContainerAwareObject target, Object objectBeingSet): objectChanged(target, objectBeingSet) {

    if (objectBeingSet instanceof DomainObjectContainer) {

        return; // Don’t call objectChanged() within setContainer() method;

    }

    target.objectChanged();

    System.out.println(“objectChanged() called.”);

}

// }}

 

// {{ Define the resolve pointcut and advice

pointcut resolve(ContainerAwareObject target): execution(* ContainerAwareObject+.get*()) && target(target);

 

before(ContainerAwareObject target): resolve(target) {

 

    /*

    * This implementation assumes that the convention has been followed

    * that getters and setters have the same name as the private variable.

    * The following code determines the private variable name from the

    * getter/setter.

*/

    try {        MethodSignature ms = ((MethodSignature) thisJoinPointStaticPart.getSignature());

        String propertyName = ms.getName().substring(3);

        String variableName = propertyName.substring(0, 1).toLowerCase() + propertyName.substring(1, propertyName.length());

 

        Class targetClass = target.getClass();

        Object var = targetClass.getDeclaredField(variableName);

        target.resolve(var);

        System.out.println(var + ” resolved.”);

 

    } catch (NoSuchFieldException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

    }

}

// }}

}