Tuesday, September 7, 2010

To DTO or not to DTO ...






In every single Enterprise Java project I am faced with the question: To DTO or not to DTO? A DTO (Data Transfer Object) is a potential design element to be used in the service layer of an enterprise system. DTOs have a single purpose: To transport data between the service layer and the presentation layer. If you use DTOs you have to pay for it. That is, you need mapping code that copies the data from your domain model to the DTOs and the other way round. On the other hand, you get additional functionality from the DTOs. For example, if you have to support multiple languages, measurement systems and currencies, all the transformation stuff can be encapsulated in mapping code that copies data between domain model and DTOs.

Over the years I´ve collected some personal guidelines that help me deciding the DTO-question in new projects. Here we go:

When NOT to use DTOs:

  • Small to mid-sized project team. That is: At max 5 people.
  • Team sits in one location.
  • No separate teams for GUI and backend.
  • If you don't use DTOs, the presentation and the backend will be tightly coupled (the domain model will be used directly in the presentation layer). This is OK if the project scope is limited and you know more or less what the product will look like in the end. It is definitely NOT OK if you work on some kind of strategic, mission critical application that is likely to live for 10-15 years and will be extended by multiple teams in the future.
  • Highly skilled team with developers that understand the technical implications of tight coupling between backend domain model and presentation. For example, if you use some kind of OR mapping framework to persist the domain model, the team has to understand under what conditions what data is available in the presentation layer.
  • Only limited I18N requirements. That is: Multiple languages are OK, multiple measurement systems, complex currency conversions and so on are not.

When to use DTOs:

  • Teams with more than 5 people. Starting with this size, teams will split up and architecture needs to take this into account (just a side note: the phenomenom that the architecture of a system corresponds to the structure of the development team is called Conway´s law). If teams split up, the tight coupling between backend and presentation is inacceptable, so we need DTOs to prevent this.
  • Teams that work distributed at several locations. The worst-case examples are projects that use some kind of nearshoring or offshoring models.
  • The need for complex mapping functionality between domain model in the backend and the presentation layer.
  • Average skilled team, you have junior developers or web-only developers in your team. The usage of DTOs allows them to use the backend services as a "black-box".
  • Reduce overhead between backend and presentation. DTOs can be optimized for certain service calls. An optimized DTO contains only those attributes that are absolutely required. Popular examples are search services, that return lists of slim DTOs. In fact, performance optimization is often the one and only argument to introduce DTOs. IMO, this factor is often overemphasized. It may be very important for "real" internet applications that produce a very high load on the backend. For enterprise systems, one should carefully consider all pros and cons before introducing DTOs on a wide scale in an archictecture "just" for performance reasons. Maybe it is good enough to optimize just the top 3 search services using sepcialized DTOs and use domain objects in all over services (especially the CRUD services).

Consequences of the usage of DTOs

As I mentioned already, DTOs don´t come for free. It is crucial to document the consequences of the introduction of DTOs in the software architecture documentation. The stakeholders of the project must understand, that DTOs are a very expensive feature of a system. The most important consequences of DTOs are:

  • You must maintain two separate models: a domain model in the backend that implements the business functionality and a DTO model that transports more or less the same data to the presentation layer.
  • Easy to understand, but nonetheless something you should mention several times to your manager: Two models cost more than one model. Most of the additional costs arise after initial development: You must synchronize both models all the time in the maintenance phase of the system.
  • Additional mapping code is necessary. You must make a well considered design decision about how the mapping logic is implemented. One extreme is the manual implementation with tons of is-not-null checks. The other extreme are mapping frameworks that promise to do all the work for you automagically. Personally, I´ve tried out both extremes and several variations inbetween and have still not found the optimal solution.

7 comments:

  1. Nice post, totally agree with you

    additionally decoding to using or not using DTO may be dependent in your application architecture & design, for example in open session view we pass entity directly to view layer or over network which is not possible with DTO. But in my experience DTO protected your application from changes in your data model. And additionally it may improve performance of application. And finally you should care about some exception (Lazy Initialization) when using entity as DTO.

    ReplyDelete
  2. Right, I forgot to mention the interface stability issue. If you need to guarantee API stability on service level, DTOs are the way to go. Thanks for your comment!

    ReplyDelete
  3. Good article. In a recent project I decided against using DTO for the additional cost and effort they produce. We use JPA with with an OSIV filter and had a few problems with attached / detached state. So, i 'm looking on how to avoid that problems for the next project. Do you have any good links or comments on how to use DTO with minimal effort? Perhaps another post your experience with the different approaches you tried so far?
    Thanks

    ReplyDelete
  4. The issue of having to synchronize the DTO model and the business model can be alleviated by using code-generating tools (annotation processing tool, XDoclet, etc.). The business model will change, but the code-generated DTOs can be recreated by just re-running the tool.

    ReplyDelete
  5. Well, "minimal effort" is relative, of course. DTOs always produce a significant overhead in a project. The approach that worked best for me until now was based on a mapping framework I´ve written myself. The basis for the framework was commons-beanutils. I´ll probably post a new article on the mapping variants later this month. Concering the idea using generated DTOs: I never tried it myself, but it certainly sounds interesting. I'm not sure if it would work for DTO models that have a significant distance to the domain model (this was the case in the project I mentioned above).

    ReplyDelete
  6. Mapping is boring, developers wants interesting problems to solve, not write repetitive code, but as a very influential .NET developer puts it, "In the fight between Don’t Repeat Yourself and Single Responsibility Principle, SRP wins, every single time." (http://ayende.com/Blog/archive/2010/09/09/maintainability-code-size-amp-code-complexity.aspx)

    ReplyDelete
  7. Great post, Gunther! Happy to see you blogging!

    ReplyDelete

Note: Only a member of this blog may post a comment.