Thursday, September 23, 2010

Domain Driven Design versus Anemic Domain Model: FIGHT!

I've been reading a bit lately about Domain Driven Design (DDD) versus the Anemic Domain Model (ADM).

On the one hand you've got folks who argue DDD is closer to 'true' Object Oriented Programming because you keep the business logic and the data together in the same class. On the other hand most of the popular Java EE frameworks 'encourage' ADM: your POJOs are just a bunch of getters and setters, then you wrap technologies like JPA, Bean Validation, Session Beans, Drools etc around them to provide business logic.

So who's right? Hmmmm? Well, I'm certainly not going to go there!

All I wanted to blog was that Metawidget doesn't mind, and works great with both approaches. This is because Metawidgets are lightweight: there's no problem combining several of them in the one screen, each pointing to a different part of your domain model.

Here are two examples you can paste into the Metawidget Live Demo editor (so you can try it right now). The first is for DDD:

import javax.swing.*; import org.metawidget.inspector.annotation.*;
import org.metawidget.inspector.composite.*; import org.metawidget.inspector.iface.*;
import org.metawidget.inspector.impl.*;
import org.metawidget.inspector.impl.propertystyle.*; import org.metawidget.inspector.impl.propertystyle.groovy.*;
import org.metawidget.inspector.java5.*; import org.metawidget.inspector.propertytype.*;
import org.metawidget.swing.*;

enum Title { Mr, Mrs, Miss }

class Person {
   Title title;

   @UiComesAfter("title")
   String firstname;

   @UiComesAfter("firstname")
   String surname;

   @UiAction
   @UiComesAfter("surname")
   void save() {
      JOptionPane.showMessageDialog(SwingUtilities.getSharedOwnerFrame(),"Save button clicked!","Save",JOptionPane.INFORMATION_MESSAGE);
   }
}

class PersonDialog extends JDialog {

   PersonDialog() {
      super(SwingUtilities.getSharedOwnerFrame(),"Domain Driven Design",true);

      PropertyStyle propertyStyle = new GroovyPropertyStyle();
      BaseObjectInspectorConfig groovyConfig = new BaseObjectInspectorConfig().setPropertyStyle(propertyStyle);
      Inspector inspector = new CompositeInspector( new CompositeInspectorConfig().setInspectors(
         new PropertyTypeInspector(groovyConfig),
         new MetawidgetAnnotationInspector(groovyConfig),
         new Java5Inspector(groovyConfig)));

      SwingMetawidget metawidget = new SwingMetawidget();
      metawidget.setInspector(inspector);
      metawidget.setToInspect(new Person());
      metawidget.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
      add(metawidget,java.awt.BorderLayout.CENTER);
      
      setSize( 400, 150 );
   }   
}

new PersonDialog().show();


And the second is for ADM:

import javax.swing.*; import org.metawidget.inspector.annotation.*;
import org.metawidget.inspector.composite.*; import org.metawidget.inspector.iface.*;
import org.metawidget.inspector.impl.*;
import org.metawidget.inspector.impl.propertystyle.*; import org.metawidget.inspector.impl.propertystyle.groovy.*;
import org.metawidget.inspector.java5.*; import org.metawidget.inspector.propertytype.*;
import org.metawidget.swing.*; import org.metawidget.swing.layout.*;

enum Title { Mr, Mrs, Miss }

class Person {
   Title title;

   @UiComesAfter("title")
   String firstname;

   @UiComesAfter("firstname")
   String surname;
}

class PersonDialog extends JDialog {

   PersonDialog() {
      super(SwingUtilities.getSharedOwnerFrame(),"Anemic Domain Model",true);

      PropertyStyle propertyStyle = new GroovyPropertyStyle();
      BaseObjectInspectorConfig groovyConfig = new BaseObjectInspectorConfig().setPropertyStyle(propertyStyle);
      Inspector inspector = new CompositeInspector( new CompositeInspectorConfig().setInspectors(
         new PropertyTypeInspector(groovyConfig),
         new MetawidgetAnnotationInspector(groovyConfig),
         new Java5Inspector(groovyConfig)));

      SwingMetawidget metawidget1 = new SwingMetawidget();
      metawidget1.setInspector(inspector);
      metawidget1.setToInspect(new Person());
      metawidget1.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
      add(metawidget1,java.awt.BorderLayout.CENTER);

      SwingMetawidget metawidget2 = new SwingMetawidget();
      metawidget2.setInspector(inspector);
      metawidget2.setToInspect(this);
      metawidget2.setMetawidgetLayout(new FlowLayout());
      add(metawidget2,java.awt.BorderLayout.SOUTH);

      setSize( 400, 150 );
   }
   
   @UiAction
   void save() {
      JOptionPane.showMessageDialog(this,"Save button clicked!",getTitle(),JOptionPane.INFORMATION_MESSAGE);
   }   
}

new PersonDialog().show();

Metawidget: it's like the Switzerland of the DDD vs ADM wars :)

0 comments: