Patrones que odio: DTO

Al poco de llegar al mundo Java (bueno, no tan poco) me encontré con el patrón DTO (Data Transfer Object) o VO.

“Data transfer object (DTO), formerly known as value objects[citation needed] or VO, is a design pattern used to transfer data between software application subsystems. DTOs are often used in conjunction with data access objects to retrieve data from a database.”

Recuerdo que nunca creí que la supuesta ventaja que ofrecía (aislar el dominio de la presentación) fuese suficiente como para que duplicar clase tras clase…

…Recuerdo también las discusiones (con una cerveza eso sí) con otros compañeros que no osaban cuestionarse la Biblia de los J2EE Core Patterns.

Sin ánimo de discutir su utilidad (no lo haré sin una cerveza por delante) y la sobrecarga que acarrea al sistema (tengo datos que lo certifican :D) afortunadamente las aproximaciones ligeras al desarrollo (desde Grails a Spring ROO en el caso de Java) se lo han cuestionado también y han decidido transferir las mismas entidades hacia la capa de presentación.

Esta aproximación es ya ampliamente utilizada en el mundo Web tradicional, pero cuando hablamos de RIAs/clientes ricos (Flex, Swing, GWT,…) no es tan sencillo pasar esas mismas Entidades.

En un próximo post contaré como invocar a DAOs de Hibernate directamente desde Flex…sin toda esa capa absurda y sobrecargada que no hace falta para mantener tablas…

KISS

Respuestas

  1. Extraño, yo también sigo teniendo discusiones sobre los DTO, y me cuesta convencer a la gente de que no sirven para nada. Es una prueba más de que el mundo de JEE llegó a perder la cabeza con los patrones de diseño y acabó creando monstruos como los EJB 2.0.

    Los DTO son un ejemplo perfecto de un patrón que sólo aporta complicación y unos beneficios más que discutibles.

    En general, es mejor no usarlos si no tienes necesidad de usarlos en sistemas distribuidos, pero también es conveniente no utilizar un sistema distribuido si puedes evitarlo.

    Al menos, eso es lo que recomiendan los mayores expertos,

    http://martinfowler.com/bliki/LocalDTO.html

    Saludos

  2. […] ya he contado en otro post sobre Spring ROO le auguro un gran futuro a medio plazo (casi ya a corto plazo diría)….a diferencia de Sun con J2EE y Java los pasos de Spring […]

  3. En mi poca experiencia veo los DTOs como VO, y en este momenot especificamente los uso para guardar la informacion consultada de mis bases de datos se podria decir que practicamente son un Array hecho clase :P, talvez no este implementando de manera completa el patron pero es la parte util que le vi o que en su momento entendi. Ahorita comenzando a trabajar en el area, estoy enfrentandome a un proyecto en swing y poco conozco de frameworks de desarrollo como Spring, espero pronto enfrentarme a ello.

  4. En mi opinion todo depende del contexto y las tecnologías empleadas. Si se trabaja con JSF, JSP, Servlets etc lo más probable es que no sean necesarios y su uso solo añadiría mayor complejidad; sin embargo, si por ejemplo se emplea GWT y App Egine seguramente tendras que usarlo porque de esta forma podras emplear algunas librerías que brindan beneficios como busqueda avanzada de texto (algo que por el momento no soporta App Engine) pero que no pueden ser compiladas a JavaScript por GWT. De no emplear el patron DTO en este caso quiza uses JSON, XML para el transporte de informacion entre el cliente GWT y el servidor (que puede implicar mayor esfuerzo) o descartar esta funcionalidad en tu aplicacion.

  5. Hola, encontré este artículo googleando sobre DTO y DAO, para resolver una duda y me ha sorprendido el texto. Quizá yo tengo una idea parcial de lo que es un DTO, pero para mí es un bean que representa una fila de una tabla en una base de datos, permitiendo a la capa de negocio «olvidarse» de las tablas. Más o menos lo que comentó harcalejo. Y en ese sentido lo encuentro muy útil y no especialmente pesado

    1. Hola Pablo,
      Los DTOs no representan un registro o fila en una tabla, en esa equivalencia que comentas eso serían la Entidad (Entity) del Modelo de Dominio.
      El DTO se crea para independizar más y que lo que viaja a otro sistema o la capa de presentación no sea la propia Entidad si no una clase que representa en general lo mismo que la Entidad pero no tan cercana al modelo de dominio.
      Este patrón (DTO) en teoría permite que si cambia el modelo de datos y el Entity el objeto con el que trabaja la pantalla (u otro sistema) no lo haga, aunque la realidad es que si cambia la tabla lo más normal es que también cambie la pantalla.
      De ahí el tema de la sobrecarga, ya que siempre implica una transformación Entidad DTO

      1. No necesariamente tiene que cambiar la pantalla, el modelo de dato y el Entity cambian para modificar la logica de negocio y formas de presentar la información en pantalla, si la operacion exige un cambio en la pantalla entonces se realiza. Mas que la sobrecarga que supuestamente causan los DTOs yo creo que es Resistencia al cambio. Entender y utlizar apropiadamente los patrones es vital para evitar la supuesta sobrecarga.

  6. Avatar de Patron EsternocleidoMastoideo
    Patron EsternocleidoMastoideo

    DTO son unas empanadas! Mas nada! Algo inutil! Porque dejar de cargar algo que es rico en contenido (Entidades) y que posee la fuerza para poder hacer las maravillas que nos brinda el jpa, por algo que no posee la información a medias?
    Para un Reporte?? en este caso la entidad no funciona como un punto final?
    En fin DTO,, pulgar abajo!

  7. Por la experiencia que tengo, el problema de los DTO’s (o VO’s) es la explosión que se produce por las diferentes necesidades de la capa de presentación. Es muy común comenzar con una definición directa de clases DTO que representan las entidades del modelo (registros de tablas: ClienteDTO, SectorDTO, PedidoDTO, ProveedorDTO…), y el enlace con las clases DAO en principio es muy clara y concisa.

    El problema es que a medida que se avanza en el diseño de un sistema empiezan a aparecer necesidades de combinar las clases del modelo para ofrecer más información, por ejemplo un listado en el que se muestren clientes con datos del sector al que pertenecen (ClienteDTO ampliado con propiedades de SectorDTO), pedidos con información del departamento que lo ha realizado y el proveedor asociado (PedidoDTO ampliado con propiedades de ProveedorDTO y PedidoDTO, etc.), y aquí es donde desde mi punto de vista se arma el lío.

    En los proyectos en los que he participado, he visto básicamente dos soluciones a este problema:

    1) Ampliar directamente los DTO de modelo incluyendo mediante agregaciones los DTO asociados, por ejemplo ClienteDTO tendría una propiedad getSector() que devolvería un objeto de tipo SectorVO. Esto tiene la ventaja de que sólo es necesario una clase VO por entidad del modelo, pero tiene dos inconvenientes muy grande: demasiada agregación, lo que implica clases VO muy profundas (ej: para acceder al tipo de sector de un pedido de un cliente, habría que hacer pedido.getCliente().getSector().getTipoSector()…) y la imposibilidad de, en un método de negocio, saber si se ha cargado una propiedad (es posible que un método de consulta DAO cargue datos de un cliente en un objeto ClienteVO, pero no los datos del sector asociado, y no hay manera de diferenciar si no está porque no existe en el modelo o porque no se cargó).

    2) Implementar un DTO para cada necesidad (un ClienteDTO, un ClienteConSectorVO, ClienteConPedidosVO…) esto último también es un problema por la cantidad de clases que resultan (una locura), y, sobre todo porque… ¿qué clases VO deben usar los DAO? ¿Es adecuado tener un ClienteDAO que tenga un método que devuelva una lista de objetos ClienteVO y otro método de consulta que devuelva la misma lista de clientes pero con los datos del sector al que pertenecen? Desde mi punto de vista no.

    Tengo que decir que yo la opción 2) la descartaría siempre, y la 1), por experiencia, sé que para proyectos pequeños (o con poca complejidad en el modelo, o con pocas combinatorias de presentación) puede estar bien.

    Últimamente he estado barajando una tercera opción, diferenciando entre «DTO’s de modelo» y «DTO’s de presentación»), pero aún no he llegado a hacer uso de ella; me he extendido demasiado.. si a alguien le interesa estoy dispuesto a exponerla y debatirla.

    Un saludo a todos

    1. Muchas gracias por tu comentario Marcos!.
      Je,je!no estoy de acuerdo con algunas cosas que dices y quizás el titular del post fue demasiado impactante, yo quería referrirme al sobredimensionamiento arquitectural de muchas aplicaciones, hay otras que sí o sí necesitan DTOs.
      En tu comentario echo en falta algunos conceptos como el Entity, ¿un DAO debe devolver DTOs? yo diría que no, que debería devolver Entities, y que la transformación de esos Entities a DTOs debe hacerse en una Capa posterior, aunque esto también es discutible 😉
      A ver si encuentro el hueco y mantenemos ese debate 🙂
      Un abrazo
      Luismi

      1. Gracias a ti por contestar; .. por los post anteriores ya me imaginaba que no estarías de acuerdo, al menos con lo de que los DAO devuelvan objetos DTO 🙂 No obstante creo que es simplemente una cuestión de nomenclatura, en la cual tampoco me quiero meter, principalmente porque hasta ahora no me he visto en la necesidad de diferenciar de una forma tan detallada las clases en un diseño… En este sentido ¿existe alguna diferencia entre los DTO y los Entity al margen de que unos representen datos de presentación y otro datos del modelo?

      2. Je,je! Conceptualmente si que con diferentes, las Entidades representan el Modelo de Dominio del Sistema, en el caso típico serán las entidades JPA que representan las tablas pero en general son las clases que representan los «nombres» del sistema.
        Y los DTOS pretenden independizar el Dominio del Sistema de lo que consumen otros clientes (en el caso sencillo un Frontal) de modo que un cambio en el modelo de dominio pudiera no afectar al cliente o viceversa :).

  8. Luis Miguel, tú lo has dicho muy bien, es una práctica muy común para los programadores para ahorrar tiempo en implementar algo que segun ellos no es necesario versus aumentar la cohesión y bajar el acoplamiento de un sistema, por ellos les encantaría devolver una clase JPA directo del servicio web hacia un cliente.. sin tener una clara definición y responsabilidades en cada capa, presentación, negocio, datos y otras.

Replica a Luis Miguel Gracia Luis Cancelar la respuesta