Recientemente escuché a personas decir que los objetos de transferencia de datos (DTO) son un antipatrón .
¿Por qué? Cuales son las alternativas?
Recientemente escuché a personas decir que los objetos de transferencia de datos (DTO) son un antipatrón .
¿Por qué? Cuales son las alternativas?
Respuestas:
Algunos proyectos tienen todos los datos dos veces . Una vez como objetos de dominio, y una vez como objetos de transferencia de datos.
Esta duplicación tiene un costo enorme , por lo que la arquitectura necesita obtener un gran beneficio de esta separación para que valga la pena.
Los DTO no son un antipatrón. Cuando envía algunos datos a través del cable (por ejemplo, a una página web en una llamada Ajax), desea asegurarse de conservar el ancho de banda enviando solo datos que utilizará el destino. Además, a menudo es conveniente que la capa de presentación tenga los datos en un formato ligeramente diferente al de un objeto comercial nativo.
Sé que esta es una pregunta orientada a Java, pero en los lenguajes .NET, los tipos anónimos, la serialización y LINQ permiten que los DTO se construyan sobre la marcha, lo que reduce la configuración y la sobrecarga de usarlos.
DTO un AntiPattern en EJB 3.0 dice:
La naturaleza pesada de Entity Beans en las especificaciones EJB anteriores a EJB 3.0, resultó en el uso de patrones de diseño como Data Transfer Objects (DTO). Los DTO se convirtieron en los objetos ligeros (que deberían haber sido los beans de entidad en sí mismos), utilizados para enviar los datos a través de los niveles ... ahora la especificación EJB 3.0 hace que el modelo de bean Entity sea el mismo objeto Java simple (POJO). Con este nuevo modelo POJO, ya no necesitará crear un DTO para cada entidad o para un conjunto de entidades ... Si desea enviar las entidades EJB 3.0 a través del nivel, simplemente implemente java.io.Serialiazable
No creo que los DTO sean un antipatrón per se, pero hay antipatrones asociados con el uso de DTO. Bill Dudney se refiere a la explosión de DTO como un ejemplo:
http://www.softwaresummit.com/2003/speakers/DudneyJ2EEAntiPatterns.pdf
También hay una serie de abusos de DTO mencionados aquí:
http://anirudhvyas.com/root/2008/04/19/abuses-of-dto-pattern-in-java-world/
Se originaron debido a los sistemas de tres niveles (típicamente usando EJB como tecnología) como un medio para pasar datos entre niveles. La mayoría de los sistemas Java modernos basados en marcos como Spring toman una vista simplificada alternativa utilizando POJO como objetos de dominio (a menudo anotados con JPA, etc.) en un solo nivel ... El uso de DTO aquí es innecesario.
Los puristas de OO dirían que DTO es antipatrón porque los objetos se convierten en representaciones de tablas de datos en lugar de objetos de dominio real.
Algunos consideran que los DTO son un antipatrón debido a sus posibles abusos. A menudo se usan cuando no deberían ser / no necesitan ser.
Este artículo describe vagamente algunos abusos.
Si está creando un sistema distribuido, los DTO ciertamente no son un antipatrón. No todos se desarrollarán en ese sentido, pero si tienes una (por ejemplo) aplicación Open Social que se ejecute sin JavaScript.
Publicará una carga de datos en su API. Esto luego se deserializa en alguna forma de objeto, típicamente un objeto DTO / Solicitud. Esto se puede validar para garantizar que los datos ingresados sean correctos antes de convertirlos en un objeto modelo.
En mi opinión, se ve como un antipatrón porque se usa mal. Si no está creando un sistema distribuido, es probable que no los necesite.
La intención de un Objeto de transferencia de datos es almacenar datos de diferentes fuentes y luego transferirlos a una base de datos (o Fachada remota ) a la vez.
Sin embargo, el patrón DTO viola el Principio de Responsabilidad Única , ya que el DTO no solo almacena datos, sino que también los transfiere desde o hacia la base de datos / fachada.
La necesidad de separar los objetos de datos de los objetos comerciales no es un antipatrón, ya que de todos modos es probable que sea necesario separar la capa de la base de datos .
En lugar de DTO, debe usar los Patrones de Agregado y Repositorio, que separa la colección de objetos ( Agregado ) y la transferencia de datos ( Repositorio ).
Para transferir un grupo de objetos, puede usar el patrón Unidad de trabajo , que contiene un conjunto de repositorios y un contexto de transacción; para transferir cada objeto en el agregado por separado dentro de la transacción.
DTO se convierte en una necesidad y no en un ANTI-PATRÓN cuando tiene todos sus objetos de dominio cargan EAGERly objetos asociados.
Si no realiza DTO, tendrá objetos transferidos innecesarios desde su capa empresarial a su capa cliente / web.
Para limitar los gastos generales para este caso, transfiera los DTO.
La pregunta no debería ser "por qué", sino " cuándo ".
Definitivamente es antipatrón cuando el único resultado de usarlo es un mayor costo : tiempo de ejecución o mantenimiento. Trabajé en proyectos que tenían cientos de DTO idénticos a las clases de entidad de base de datos. Cada vez que deseaba agregar un solo campo, agregaba la identificación como cuatro veces: a DTO, a entidad, a conversión de DTO a clases o entidades de dominio, la conversión inversa, ... Olvidó algunos de los lugares y datos obtenidos inconsistente.
No es antipatrón cuando realmente necesita una representación diferente de las clases de dominio. : más plana, más rica, más estrecha, ...
Personalmente, comienzo con la clase de dominio y la paso, con la verificación adecuada en los lugares correctos. Puedo anotar y / o agregar algunas clases "auxiliares" para hacer asignaciones, a bases de datos, a formatos de serialización como JSON o XML ... Siempre puedo dividir una clase en dos si siento la necesidad.
Se trata de su punto de vista: prefiero ver un objeto de dominio como un solo objeto que desempeña varios roles, en lugar de múltiples objetos creados entre sí. Si el único rol que tiene un objeto es transportar datos, entonces es DTO.
Creo que la gente quiere decir que podría ser un antipatrón si implementa todos los objetos remotos como DTO. Un DTO es simplemente un conjunto de atributos y si tiene objetos grandes, siempre transferirá todos los atributos, incluso si no los necesita o no los usa. En este último caso, prefiera usar un patrón Proxy.