Qu'est-ce que Data Transfer Object?

218

Qu'est-ce qu'un objet de transfert de données?

Dans MVC, les classes de modèle sont-elles DTO, et sinon quelles sont les différences et avons-nous besoin des deux?

Yaron Naveh
la source
@ yegor256 et le fait, ce livre dans cet article sait comment récupérer des données de l'API et aussi comment stocker des données dans la base de données, et donc violer SRP, est-ce correct?
Betlista

Réponses:

223

Un objet de transfert de données est un objet utilisé pour encapsuler des données et les envoyer d'un sous-système d'une application à une autre.

Les DTO sont le plus souvent utilisés par la couche Services dans une application N-Tier pour transférer des données entre elle et la couche UI. Le principal avantage ici est qu'il réduit la quantité de données qui doivent être envoyées sur le câble dans les applications distribuées. Ils font également de grands modèles dans le modèle MVC.

Une autre utilisation des DTO peut être d'encapsuler des paramètres pour les appels de méthode. Cela peut être utile si une méthode prend plus de 4 ou 5 paramètres.

Lorsque vous utilisez le modèle DTO, vous utiliserez également des assembleurs DTO. Les assembleurs sont utilisés pour créer des DTO à partir d'objets de domaine et vice versa.

La conversion de Domain Object en DTO et vice versa peut être un processus coûteux. Si vous ne créez pas d'application distribuée, vous ne verrez probablement pas de grands avantages du modèle, comme l' explique Martin Fowler ici

Benny Hallett
la source
7
"DTO fait de grands modèles dans le modèle MVC" - mais un modèle ne devrait-il pas contenir toutes les données de l'objet et DTO devrait-il être optimisé avec une partie des données? Si j'ai le modèle A et que je dois le transmettre à deux sous-systèmes, y aura-t-il A_DTO_1 et A_DTO_2 avec les champs appropriés de chacun? "Les DTO peuvent être pour encapsuler des paramètres pour les appels de méthode" -> Donc, chaque classe qui encapsule les paramètres est DTO même si ce n'est pas un système distribué? Les modèles dans MVC ne sont-ils pas l'objet de domaine?
Yaron Naveh
2
En réponse à votre première question, je ne pense pas que nous parlions de la même chose. Le modèle dans MVC n'a pas nécessairement besoin d'être une classe de votre modèle de domaine. Cela dit, cela pourrait bien l'être. L'utilisation du DTO supprime toutes les choses inutiles. Tout dépend de l'architecture que vous recherchez. Je ne sais pas exactement comment répondre à votre deuxième question. Que ce soit à travers le câble ou non, c'est toujours un objet qui encapsule un tas de données à transférer entre les (sous) systèmes, donc je dirais que c'est un DTO.
Benny Hallett
12
"Une autre utilisation des DTO peut être d'encapsuler des paramètres pour les appels de méthode. Cela peut être utile si une méthode prend plus de 4 ou 5 paramètres." Il s'agit en fait d'un anti-modèle appelé classe Poltergeist ou Gypsy Wagon. Si votre méthode a besoin de 4 arguments, donnez-lui 4, ne créez pas de classe juste pour déplacer un objet dans une méthode ou une classe.
Wix
2
@Wix, bon point. Je dirais cependant que c'est correct si c'est sémantiquement correct (disons si vous passez une classe de paramètres avec des propriétés plutôt que les propriétés elles-mêmes en tant que valeurs). Ce que vous ne devriez pas faire, c'est jeter tous les arguments pour passer un seul objet, car ils peuvent très bien être sans rapport et provoquer des cauchemars se démêlant plus tard.
Aram Kocharyan
3
Les DTO ne doivent pas être utilisés pour encapsuler les paramètres des appels de méthodes (ce qui en ferait des LocalDTO), ils ont été introduits dans le contexte des interfaces distantes: martinfowler.com/bliki/LocalDTO.html
Rui
28

La définition de DTO peut être trouvée sur le site de Martin Fowler . Les DTO sont utilisés pour transférer des paramètres vers des méthodes et comme types de retour. Beaucoup de gens les utilisent dans l'interface utilisateur, mais d'autres en gonflent des objets de domaine.

blu
la source
22

Un DTO est un objet stupide - il détient juste des propriétés et a des getters et setters, mais aucune autre logique de quelque importance (autre qu'une implémentation compare () ou equals ()).

En règle générale, les classes de modèle dans MVC (en supposant que .net MVC ici) sont des DTO, ou des collections / agrégats de DTO

Eric Petroelje
la source
3
Ce que vous décrivez est un LocalDTO: martinfowler.com/bliki/LocalDTO.html
Rui
3
Un cas où il est utile d'utiliser quelque chose comme un DTO est lorsque vous avez un décalage important entre le modèle dans votre couche de présentation et le modèle de domaine sous-jacent. Dans ce cas, il est logique de créer une façade / passerelle spécifique à la présentation qui mappe à partir du modèle de domaine et présente une interface pratique pour la présentation.
Amitābha
14

En général, les objets de valeur doivent être immuables. Comme les objets Integer ou String en Java. Nous pouvons les utiliser pour transférer des données entre les couches logicielles. Si les couches ou services logiciels s'exécutent dans différents nœuds distants, comme dans un environnement de microservices ou dans une ancienne application Java Enterprise. Nous devons faire des copies presque exactes de deux classes. C'est là que nous avons rencontré les DTO.

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

Dans les systèmes Java Enterprise Systems hérités, les DTO peuvent contenir divers éléments EJB.

Je ne sais pas si c'est une meilleure pratique ou non, mais j'utilise personnellement des objets de valeur dans mes projets Spring MVC / Boot comme ceci:

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

La couche contrôleur ne sait pas quelles sont les entités. Il communique avec les objets Form et View Value . Form Objects a des annotations de validation JSR 303 (par exemple @NotNull) et View Value Objects a des annotations Jackson pour la sérialisation personnalisée. (par exemple @JsonIgnore)

La couche de service communique avec la couche de référentiel via l'utilisation d'objets d'entité. Les objets d'entité comportent des annotations JPA / Hibernate / Spring Data. Chaque couche communique uniquement avec la couche inférieure. La communication entre couches est interdite en raison d'une dépendance circulaire / cyclique.

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

Certains Frameworks ORM ont la capacité de projection via l'utilisation d'interfaces ou de classes supplémentaires. Les référentiels peuvent donc retourner directement les objets View. Là, vous n'avez pas besoin d'une transformation supplémentaire.

Par exemple, c'est notre entité Utilisateur:

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

Mais vous devez renvoyer une liste paginée d'utilisateurs qui incluent simplement id, prénom, nom. Vous pouvez ensuite créer un objet Afficher la valeur pour la projection ORM.

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

Vous pouvez facilement obtenir le résultat paginé de la couche de référentiel. Grâce au printemps, vous pouvez également utiliser uniquement des interfaces pour les projections.

List<UserListItemView> find(Pageable pageable);

Ne vous inquiétez pas pour les autres BeanUtils.copyméthodes de conversion qui fonctionnent très bien.

Fırat KÜÇÜK
la source
11
  1. Pour moi, la meilleure réponse à la question de savoir ce qu'est un DTO est que les DTO sont des objets simples qui ne doivent contenir aucune logique métier ou implémentation de méthodes qui nécessiteraient des tests .
  2. Normalement, votre modèle (en utilisant le modèle MVC) sont des modèles intelligents, et ils peuvent contenir beaucoup / certaines méthodes qui effectuent spécifiquement différentes opérations pour ce modèle (pas la logique métier, cela devrait être au niveau des contrôleurs). Cependant, lorsque vous transférez des données (par exemple, en appelant un point de terminaison REST ( GET/ POST/ quoi que ce soit) de quelque part, ou en consommant un service Web à l'aide de SOA, etc.), vous ne voulez pas transmettre l'objet de grande taille avec du code qui n'est pas nécessaire pour le point de terminaison consommera des données et ralentira le transfert.
Thiago Burgos
la source
Pourquoi la logique métier devrait-elle être dans les contrôleurs?
AlexioVay
6

Avec MVC, les objets de transfert de données sont souvent utilisés pour mapper des modèles de domaine à des objets plus simples qui seront finalement affichés par la vue.

De Wikipédia :

L'objet de transfert de données (DTO), anciennement appelé objets de valeur ou VO, est un modèle de conception utilisé pour transférer des données entre des sous-systèmes d'application logicielle. Les DTO sont souvent utilisés en conjonction avec des objets d'accès aux données pour récupérer les données d'une base de données.

Dan
la source
3
Un objet de valeur n'est pas un DTO .
coderpc
0

L'objet de transfert de données (DTO) décrit «un objet qui transporte des données entre les processus» (Wikipedia) ou un «objet qui est utilisé pour encapsuler des données et les envoyer d'un sous-système d'une application à une autre» (réponse Stack Overflow).

mostafa kazemi
la source
0

DefN

Un DTO est un modèle de données codé en dur . Il ne résout que le problème de la modélisation d'un enregistrement de données géré par un processus de production codé en dur , où tous les champs sont connus au moment de la compilation et donc accessibles via des propriétés fortement typées.

En revanche, un modèle dynamique ou «sac de propriétés» résout le problème de la modélisation d'un enregistrement de données lorsque le processus de production est créé au moment de l'exécution.

Le Cvar

Un DTO peut être modélisé avec des champs ou des propriétés, mais quelqu'un a inventé un conteneur de données très utile appelé Cvar. C'est une référence à une valeur. Lorsqu'un DTO est modélisé avec ce que j'appelle des propriétés de référence , les modules peuvent être configurés pour partager la mémoire du tas et ainsi travailler en collaboration sur celle-ci. Cela élimine complètement le passage de paramètres et la communication O2O de votre code. En d'autres termes, les DTO ayant des propriétés de référence permettent au code de réaliser un couplage nul .

    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; } // >;)
    }

Source: http://www.powersemantics.com/

Les DTO dynamiques sont un composant nécessaire pour les logiciels dynamiques. Pour instancier un processus dynamique, une étape du compilateur consiste à lier chaque machine du script aux propriétés de référence définies par le script. Un DTO dynamique est créé en ajoutant les Cvars à une collection.

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

Contentions

Remarque: parce que Wix a étiqueté l'utilisation des DTO pour organiser les paramètres comme un "anti-modèle", je vais donner un avis faisant autorité.

    return View(model);  // MVC disagrees

Mon architecture collaborative remplace les modèles de conception. Reportez-vous à mes articles Web.

Les paramètres permettent un contrôle immédiat d'une machine à châssis de pile. Si vous utilisez un contrôle continu et n'avez donc pas besoin d'un contrôle immédiat, vos modules n'ont pas besoin de paramètres. Mon architecture n'en a pas. La configuration in-process des machines (méthodes) ajoute de la complexité mais aussi de la valeur (performances) lorsque les paramètres sont des types de valeur. Cependant, les paramètres de type de référence font que le consommateur ne parvient pas à retirer les valeurs du tas de toute façon - il suffit donc de configurer le consommateur avec des propriétés de référence. Fait de l'ingénierie mécanique: la dépendance aux paramètres est une sorte de préoptimisation, car le traitement (fabrication de composants) est lui-même un déchet. Reportez-vous à mon article W pour plus d'informations. http://www.powersemantics.com/w.html .

Fowler et l'entreprise pourraient réaliser les avantages des DTO en dehors de l'architecture distribuée s'ils avaient déjà connu une autre architecture. Les programmeurs ne connaissent que les systèmes distribués. Les systèmes collaboratifs intégrés (alias production alias fabrication) sont quelque chose que je devais revendiquer comme ma propre architecture, car je suis le premier à écrire du code de cette façon.

Certains considèrent le DTO comme un modèle de domaine anémique, ce qui signifie qu'il manque de fonctionnalités, mais cela suppose qu'un objet doit posséder les données avec lesquelles il interagit. Ce modèle conceptuel vous oblige ensuite à livrer les données entre les objets, qui est le modèle de traitement distribué. Cependant sur une ligne de fabrication, chaque étape peut accéder au produit final et le modifier sans le posséder ni le contrôler. C'est la différence entre le traitement distribué et le traitement intégré. La fabrication sépare le produit des opérations et de la logistique.

Il n'y a rien de mal à modéliser le traitement en tant que groupe d'employés de bureau inutiles qui travaillent par courrier électronique sans garder de trace de courrier électronique, à l'exception de tout le travail supplémentaire et des maux de tête qu'il crée dans la gestion des problèmes de logistique et de retour. Un processus distribué correctement modélisé joint un document (routage actif) au produit décrivant les opérations dont il est issu et vers lesquelles il ira. Le routage actif est une copie du routage de la source de processus, qui est écrite avant le début du processus. En cas de défaut ou autre changement d'urgence, le routage actif est modifié pour inclure les étapes de fonctionnement auxquelles il sera envoyé. Cela représente alors tout le travail qui est entré en production.

RBJ
la source