Data Transfer Object

When you are using the pattern FacadesAsDistributedComponents, the question of data transfer across the network from client to facade comes up. You could go down to a least common denominator of using primitive types as the arguments to your networked calls, but that is a pain to program, not to mention very un OO. So, the conclusion that most people come to is that you need to use some sort of Serializable object, e.g. a DataTransferObject that can carry data back and forth betweeen client and server.

This approach works in any distributed computing environment that allows pass-by-value. In our case, we've used this in both RMI and EJB (which uses RMI over IIOP).

-- KyleBrown


I used a very cheap and cheerful message object on a previous project, simply consisting of a message id and Hashtable containing name/value pairs. I used some checking to ensure the objects being placed in the hashtable were serializable. Then at the other end of the network, the handler simply checked the id and then requested the named values from the object to perform its task. Not sure how efficient this is, and I suppose it would have been more OO to have defined a base message object and declared sub-types, but it was only a demo application and allowed us to define new message content easily enough.

-- StuartBarker

''"cheerful message object"? This is a technical term? There are also sullen message objects? Or is this a way of saying you whistle while you do distributed work?


This is something we looked at a long time ago in Smalltalk, but I guess it still holds in Java. The reason you want to use an actual type rather than a Hashtable is that the lookup of instance variables is orders of magnitude faster than looking something up in a hashtable. It also has nice features from a type safety perspective.

-- KyleBrown

You could use an Object array instead of a Hashtable. Use ints (or type-safe enums) to index the array. The enum (or some a other external specification) could also prescribe the type of the field for type checking. Admittedly, this would have to be a runtime check.

 public void set(Field field, Object value) {
     if (!field.getValueClass().isInstance(value)) {
         throw new ClassCastException();
     }
     data[field.getIndex()] = value;
 }
-- BenArnold


MartinFowler describes this pattern here: http://martinfowler.com/eaaCatalog/dataTransferObject.html


There is a popular design pattern, especially in Java, called the data transfer object (DTO). The idea is to have a simple class to transfer data between tiers in a multi-tiered architecture. The DTO is typically implemented as a class with a bunch of fields, and getters and setters for each field.

Since every DTO class is essentially the same, except the field names and data types, why have I never seen this refactored? Isn't a generic DTO a simpler solution? If the data constraints were defined in a generic way then a simple user interface could be built automatically: create, search, modify, delete. Add a field to the canonical representation of an data entity and it flows automatically through the rest of the system without any additional coding.

Has anyone seen this done? Or is there something fundamentally wrong with it?

-- BenArnold

Yup, that's a recordset, and it kills the advantage of static typing and you end up always trying to figure out what's in it. Better to use real objects with real properties. aPerson.Name is better than aPerson["Name"], because it's easier to maintain in the face of change, the compiler will help you.

The book SmalltalkBestPracticePatterns calls the fix the VariableStatePattern?. That means you don't declare fields in Java, you declare a map of strings to values, and then name each value. All database rows follow this pattern, so ActivexDataObjects? also provides DTOs. -- PhlIp

I'm not advocating throwing out typing altogether. I've known people who have been on projects where the DTO was a HashMap. They said it was far more hassle than it was worth precisely because of the lack of type checking. I would like to use a data transfer object that was constrained to a particular schema, like a class definition, but checked at runtime.

Yes, you lose compiler checking, but you still have runtime type checking, and you get all the benefits of being able to write generic code for every kind of data your application has to handle: generic GUI forms, generic web forms, generic reports, whatever.

-- BenArnold


Hi Ben.

What you are talking about is exactly what I did recently. I don't know if I broke some "sacred" rule, but my generic DTO looks like this:

public interface DTOList extends Serializable {

    public Iterator iterator();
    public int size();
    public boolean contains(Object o);
    public boolean containsAll(Collection c);
    public boolean equals(Object o);
    public int hashCode();
    public boolean isEmpty();
    public Object[] toArray();
    public Object[] toArray(Object[] a);

static class MutableDTO extends ArrayList implements DTOList { }
} /* //Create the Transfer Object to send back to client. DTOList.MutableDTO result = new DTOList.MutableDTO(); // ... read database into DTO_DetailsX result.add(DTO_DetailsX); return result; I can see the anti-"Cast"ers cringing. But if you're requesting a DTO from a DAO into a known DTO type, then casting it to that DTO type isn't a stretch.

Someone let me know if they see any glaring problem with this. Currently I'm using it strictly for POJO apps.

-- RMCH

See: DomainObjectStateHolder, BagOfJumpingBeans, StateObject, RestArchitecture.


CategoryPattern

EditText of this page (last edited January 14, 2013) or FindPage with title or text search