Having worked a lot with EMF and Eclipse RCP applications based on EMF as the framework of choice for transferring domain models into code, I never got in touch with real-life examples of Data Transfer Objects (DTOs). I was familiar with the pattern in theory, but I never saw a DTO in practice since EMF works fine without them, even in a client-server architecture.
This changed recently. My new project is a client-server system which does not use EMF for implementing its domain objects. DTOs are used heavily to transfer data from the server to the client and vice versa. During my first journeys through the unknown code base, I stumbled upon a lot of DTOs and wondered what they were needed for at all since they seemed to introduce a lot of redundancy and required a mapping to and from the entities managed by the server. Wouldn't it be more efficient and practical to simply use the entities as the shared domain objects on the server and the client? What is right in the EMF world cannot be wrong in the JavaEE world, I thought.
So I did some research and found this blog post by Adam Bien who seemed to confirm my doubts. "JavaEE 7 retired the DTO" was all I needed to hear in order to start a discussion with one of my new colleagues about the whole purpose of DTOs in our project. He was nice enough to take a long break from his current task and give me an extended explanation of why and how DTOs are necessary in our project. He answered all of my questions patiently, even if some of them were perhaps a bit naive and showed my lack of experience with some aspects of JavaEE. Needless to say it was a fruitful discussion.
I did some more research the next day based on his explanation. When I was finished, I had changed my mind. I am now convinced DTOs add value to our project despite the code duplication and the extra efforts for the domain mapping because they embody more than a simple transfer mechanism . Here are the pros and cons of DTOs based on my current understanding:
- Duplicate code (duplicate data models, duplicate constraints,...)
- A mapping to and from the domain objects is required
- DTO exposes the domain model in a form that is tailored for the client's needs
- Entity should be managed by the server all the time, never deattached from it
- Can save bandwidth by carrying only a selected subset of the entity's attributes/dependencies
- No client dependency on JPA if entity uses JPA annotations (e.g. for constraints)
- More pros here on Adam Bien's blog (2014)
Resources I found helpful