¿Qué es el objeto de transferencia de datos?


Respuestas:


222

Un objeto de transferencia de datos es un objeto que se utiliza para encapsular datos y enviarlos de un subsistema de una aplicación a otro.

Los DTO son los más utilizados por la capa de Servicios en una aplicación N-Tier para transferir datos entre sí y la capa de IU. El principal beneficio aquí es que reduce la cantidad de datos que deben enviarse a través del cable en aplicaciones distribuidas. También hacen excelentes modelos en el patrón MVC.

Otro uso para los DTO puede ser encapsular parámetros para llamadas a métodos. Esto puede ser útil si un método toma más de 4 o 5 parámetros.

Al usar el patrón DTO, también utilizaría ensambladores DTO. Los ensambladores se utilizan para crear DTO a partir de objetos de dominio y viceversa.

La conversión de objeto de dominio a DTO y viceversa puede ser un proceso costoso. Si no está creando una aplicación distribuida, probablemente no verá grandes beneficios del patrón, como explica Martin Fowler aquí


77
"DTO hace grandes modelos en el patrón MVC", pero ¿no debería un modelo contener todos los datos del objeto y DTO debe optimizarse con parte de los datos? Si tengo el modelo A y necesito pasarlo a dos subsistemas, ¿habrá A_DTO_1 y A_DTO_2 con los campos relevantes de cada uno? "Los DTO pueden ser para encapsular parámetros para llamadas a métodos" -> Entonces, ¿cada clase que envuelve parámetros es DTO incluso si este no es un sistema distribuido? ¿No son los modelos en MVC el objeto de dominio?
Yaron Naveh

2
En respuesta a su primera pregunta, no creo que hablemos de lo mismo. El modelo en MVC no necesariamente debe ser una clase de su Modelo de dominio. Habiendo dicho eso, bien podría ser. Usar el DTO elimina todas las cosas innecesarias. Solo depende de la arquitectura que busques. No estoy seguro exactamente cómo responder a su segunda pregunta. Ya sea a través del cable o no, sigue siendo un objeto que encapsula una gran cantidad de datos para ser transferidos entre (sub) sistemas, por lo que diría que es un DTO.
Benny Hallett el

12
"Otro uso para los DTO puede ser encapsular parámetros para llamadas a métodos. Esto puede ser útil si un método toma más de 4 o 5 parámetros". Esto es en realidad un antipatrón llamado clase Poltergeist o Gypsy Wagon. Si su método necesita 4 argumentos, dele 4, no cree una clase solo para mover un objeto a un método o una clase.
Wix

2
@Wix, buen punto. Sin embargo, argumentaría que esto está bien si es semánticamente correcto (por ejemplo, si pasa una clase de configuración con propiedades en lugar de las propiedades mismas como valores). Lo que no debe hacer es incluir todos los argumentos para pasar un solo objeto, ya que es muy posible que no estén relacionados y causen pesadillas que se desenreden más adelante.
Aram Kocharyan

3
Los DTO no deben usarse para encapsular parámetros para llamadas a métodos (lo que los convertiría en LocalDTO), se introdujeron en el contexto de interfaces remotas: martinfowler.com/bliki/LocalDTO.html
Rui

28

La definición de DTO se puede encontrar en el sitio de Martin Fowler . Los DTO se utilizan para transferir parámetros a métodos y como tipos de retorno. Mucha gente usa esos en la interfaz de usuario, pero otros inflan objetos de dominio de ellos.


22

Un DTO es un objeto tonto: solo contiene propiedades y tiene captadores y establecedores, pero ninguna otra lógica de importancia (aparte de una implementación de comparación () o igual ()).

Por lo general, las clases de modelos en MVC (suponiendo .net MVC aquí) son DTO, o colecciones / agregados de DTO


3
Lo que está describiendo es un LocalDTO: martinfowler.com/bliki/LocalDTO.html
Rui

3
Un caso en el que es útil usar algo como un DTO es cuando tiene una discrepancia significativa entre el modelo en su capa de presentación y el modelo de dominio subyacente. En este caso, tiene sentido hacer una fachada / puerta de enlace específica para la presentación que mapee desde el modelo de dominio y presente una interfaz que sea conveniente para la presentación.
Amitābha

14

En general, los objetos de valor deben ser inmutables. Al igual que los objetos Integer o String en Java. Podemos usarlos para transferir datos entre capas de software. Si las capas o servicios de software se ejecutan en diferentes nodos remotos, como en un entorno de microservicios o en una aplicación Java Enterprise heredada. Debemos hacer copias casi exactas de dos clases. Aquí es donde nos encontramos con los DTO.

|-----------|                                                   |--------------|
| SERVICE 1 |--> Credentials DTO >--------> Credentials DTO >-- | AUTH SERVICE |
|-----------|                                                   |--------------|

En sistemas Java Enterprise heredados, los DTO pueden tener varias cosas EJB.

No sé si esta es una práctica recomendada o no, pero personalmente uso Value Objects en mis proyectos Spring MVC / Boot como este:

        |------------|         |------------------|                             |------------|
-> Form |            | -> Form |                  | -> Entity                   |            |
        | Controller |         | Service / Facade |                             | Repository |
<- View |            | <- View |                  | <- Entity / Projection View |            |
        |------------|         |------------------|                             |------------|

La capa de controlador no sabe cuáles son las entidades. Se comunica con Formulario y Ver objetos de valor . Form Objects tiene anotaciones de validación JSR 303 (por ejemplo, @NotNull) y View Value Objects tiene anotaciones de Jackson para la serialización personalizada. (por ejemplo @JsonIgnore)

La capa de servicio se comunica con la capa de repositorio mediante el uso de objetos de entidad. Los objetos de entidad tienen anotaciones de datos JPA / Hibernate / Spring. Cada capa se comunica solo con la capa inferior. La comunicación entre capas está prohibida debido a la dependencia circular / cíclica.

User Service ----> XX CANNOT CALL XX ----> Order Service

Algunos marcos ORM tienen la capacidad de proyección mediante el uso de interfaces o clases adicionales. Por lo tanto, los repositorios pueden devolver objetos View directamente. Ahí no necesitas una transformación adicional.

Por ejemplo, esta es nuestra entidad de usuario:

@Entity
public final class User {
    private String id;
    private String firstname;
    private String lastname;
    private String phone;
    private String fax;
    private String address;
    // Accessors ...
}

Pero debe devolver una lista paginada de usuarios que solo incluya id, nombre y apellido. Luego puede crear un objeto de valor de vista para la proyección ORM.

public final class UserListItemView {
    private String id;
    private String firstname;
    private String lastname;
    // Accessors ...
}

Puede obtener fácilmente el resultado paginado de la capa de repositorio. Gracias a Spring también puede usar solo interfaces para proyecciones.

List<UserListItemView> find(Pageable pageable);

No se preocupe por otro BeanUtils.copymétodo de operaciones de conversión que funciona bien.


11
  1. Para mí, la mejor respuesta a la pregunta de qué es un DTO es que los DTO son objetos simples que no deben contener ninguna lógica de negocio o implementación de métodos que requieran pruebas .
  2. Normalmente su modelo (usando el patrón MVC) son modelos inteligentes, y pueden contener muchos / algunos métodos que realizan algunas operaciones diferentes para ese modelo específicamente (no la lógica de negocios, esto debería estar en los controladores). Sin embargo, cuando transfiere datos (por ejemplo, llamando a un punto final REST ( GET/ POST/ lo que sea) desde algún lugar, o consumiendo un servicio web usando SOA, etc.) no desea transmitir el objeto de gran tamaño con código que no es necesario para el punto final, consumirá datos y ralentizará la transferencia.

¿Por qué la lógica de negocios debería estar en los controladores?
AlexioVay

6

Con MVC, los objetos de transferencia de datos a menudo se utilizan para asignar modelos de dominio a objetos más simples que finalmente se mostrarán en la vista.

De Wikipedia :

El objeto de transferencia de datos (DTO), anteriormente conocido como objetos de valor o VO, es un patrón de diseño utilizado para transferir datos entre subsistemas de aplicaciones de software. Los DTO a menudo se usan junto con objetos de acceso a datos para recuperar datos de una base de datos.


3
Un objeto de valor no es un DTO .
coderpc

0

El objeto de transferencia de datos (DTO) describe "un objeto que transporta datos entre procesos" (Wikipedia) o un "objeto que se utiliza para encapsular datos y enviarlos de un subsistema de una aplicación a otro" (respuesta de desbordamiento de pila).


0

DefN

Un DTO es un modelo de datos codificado . Solo resuelve el problema de modelar un registro de datos manejado por un proceso de producción codificado , donde todos los campos se conocen en tiempo de compilación y, por lo tanto, se accede a ellos a través de propiedades fuertemente tipadas.

Por el contrario, un modelo dinámico o "bolsa de propiedades" resuelve el problema de modelar un registro de datos cuando el proceso de producción se crea en tiempo de ejecución.

El cvar

Un DTO puede modelarse con campos o propiedades, pero alguien inventó un contenedor de datos muy útil llamado Cvar. Es una referencia a un valor. Cuando un DTO se modela con lo que yo llamo propiedades de referencia , los módulos se pueden configurar para compartir memoria de almacenamiento dinámico y, por lo tanto, trabajar en colaboración en él. Esto elimina completamente el paso de parámetros y la comunicación O2O de su código. En otras palabras, los DTO que tienen propiedades de referencia permiten que el código logre el acoplamiento cero .

    class Cvar { ... }

    class Cvar<T> : Cvar
    {
        public T Value { get; set; }
    }

    class MyDTO
    {
        public Cvar<int> X { get; set; }
        public Cvar<int> Y { get; set; }
        public Cvar<string> mutableString { get; set; } // >;)
    }

Fuente: http://www.powersemantics.com/

Los DTO dinámicos son un componente necesario para el software dinámico. Para crear una instancia de un proceso dinámico, un paso del compilador es vincular cada máquina en el script a las propiedades de referencia que define el script. Se crea un DTO dinámico agregando los Cvars a una colección.

    // a dynamic DTO
    class CvarRegistry : Dictionary<string, Cvar> { }

Contenciones

Nota: debido a que Wix etiquetó el uso de DTO para organizar parámetros como un "antipatrón", daré una opinión autorizada.

    return View(model);  // MVC disagrees

Mi arquitectura colaborativa reemplaza los patrones de diseño. Consulte mis artículos web.

Los parámetros proporcionan un control inmediato de una máquina de estructura de pila. Si usa control continuo y, por lo tanto, no necesita control inmediato, sus módulos no necesitan parámetros. Mi arquitectura no tiene ninguno. La configuración en proceso de máquinas (métodos) agrega complejidad pero también valor (rendimiento) cuando los parámetros son tipos de valor. Sin embargo, los parámetros de tipo de referencia hacen que el consumidor provoque errores de caché para quitar los valores del montón de todos modos, por lo tanto, solo configure el consumidor con propiedades de referencia. Hecho de la ingeniería mecánica: la confianza en los parámetros es una especie de optimización previa, porque el procesamiento (fabricación de componentes) en sí mismo es un desperdicio. Consulte mi artículo W para obtener más información. http://www.powersemantics.com/w.html .

Fowler y la compañía podrían darse cuenta de los beneficios de los DTO fuera de la arquitectura distribuida si hubieran conocido alguna otra arquitectura. Los programadores solo conocen sistemas distribuidos. Los sistemas colaborativos integrados (también conocidos como producción o fabricación) son algo que tuve que reclamar como mi propia arquitectura, porque soy el primero en escribir código de esta manera.

Algunos consideran que el DTO es un modelo de dominio anémico, lo que significa que carece de funcionalidad, pero esto supone que un objeto debe poseer los datos con los que interactúa. Este modelo conceptual lo obliga a entregar los datos entre objetos, que es el modelo para el procesamiento distribuido. Sin embargo, en una línea de fabricación, cada paso puede acceder al producto final y cambiarlo sin tenerlo ni controlarlo. Esa es la diferencia entre el procesamiento distribuido e integrado. La fabricación separa el producto de las operaciones y la logística.

No hay nada intrínsecamente malo con el procesamiento de modelado, ya que un grupo de empleados de oficina inútiles que se envían correos electrónicos trabajan entre ellos sin mantener un rastro de correo electrónico, excepto por todo el trabajo extra y el dolor de cabeza que genera al manejar la logística y los problemas de devolución. Un proceso distribuido modelado correctamente adjunta un documento (enrutamiento activo) al producto que describe de qué operaciones provino y a dónde irá. El enrutamiento activo es una copia del enrutamiento de origen del proceso, que se escribe antes de que comience el proceso. En el caso de un defecto u otro cambio de emergencia, la ruta activa se modifica para incluir los pasos de operación a los que se enviará. Esto explica todo el trabajo que entró en producción.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.