This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
Your book has a section on "Eliminating DTOs". Why should Data Transfer Objects be avoided? What pattern should replace them?
In the application my team is currently developing, we've made extensive use of DTOs and the Transfer Object Assembler pattern. These patterns have allowed us to reduce the number of calls to EJBs and decouple the client from the complexity of the data model.
As another Scott whose used DTO's as well, how do you transfer data without exposing the backend without using DTO's? I'm curious too, since DTO's have many positive features. [ January 24, 2006: Message edited by: Scott Selikoff ]
ORM frameworks such as Hibernate, JDO and EJB 3 support what are called detached objects. These are previously persistent objects that are "disconnected/detached" from the database and returned by the business tier back to the presentation tier.
Returning the detached objects eliminates the need to instantiate the DTOs that mirror the domain objects. For example, rather than instantiating AccountDTO and copying data into it from Account, the business tier simply returns the Account. In my experience this works well. It cuts down on the "boring" domain DTO and DTO assembler code.
But sometimes there is a concern about exposing too much of the domain model to presentation tier. One solution for a domain object to implement a "view" interface, which defines the API it exposes to the presentation tier. For example, Account could implement AccountView interface, which exposes getters such as getBalance() and hides Account.debit() and Account.credit(). Another option is to return adapters that delegate to the real domain object. This requires most code but less than having DTOs.
Of course, whether DTO-free approach works for your application depends on your particular requirements.
Enterprise Java consulting and training - <a href="http://www.chrisrichardson.net" target="_blank" rel="nofollow">http://www.chrisrichardson.net</a> Author, POJOs in Action - <a href="http://www.manning.com/crichardson" target="_blank" rel="nofollow">http://www.manning.com/crichardson</a> Enterprise POJOs blog - <a href="http://chris-richardson.blog-city.com" target="_blank" rel="nofollow">http://chris-richardson.blog-city.com</a>
Where I've seen DTO's having the most use over detached data source BOs is when data types are involved. For example, the user may enter the date/time separately on JSP page that gets converted to a DTO, but the database might store these two separate fields as one. There's other such examples such as when you want the client to sent raw/uncoverted data, that the application tier should convert/process before saving as a BO.
I guess where I see it becoming difficult is when DTOs map to multiple BOs and/or DTO's map multiple fields to single fields in BOs. Even with defining an API, managing the conversion between views and bos could be difficult.
Although I have seen a number of cases where the DTO's and BO's were virtually identical, so its not always this difficult to weed DTO's out. I suppose I still object to getting rid of them all together for EJB service or web service type applications since it exposes backend structures I'd prefer to abstract away from the user.
Joined: Aug 24, 2005
In the application I mentioned above, I have some issues similar to what Scott mentions.
There are datatype differences between the client and the data model. My Assembler object is filtering some of the collection data before populating the DTOs. The fields in the DTO reflect the client code's requirements and do not map nicely to the data model.
The DTO and Assembler pattern have allowed me to decouple the client from the data model, but the cost is a lot of "boring" code.
Your suggestion about the view interface is very interesting. I think I can use this concept to refactor and simplify some of my objects.