Pourquoi les objets de transfert de données (Dto) sont-ils un anti-motif?
J'ai récemment entendu des gens dire que les objets de transfert de données (Dto) sont un anti-pattern.
Pourquoi? Quelles sont les alternatives?
11 réponses
Certains projets ont toutes les données deux fois. Une fois comme objets de domaine, et une fois comme objets de transfert de données.
Cette duplication a un coût énorme, donc l'architecture doit tirer un énorme avantage de cette séparation pour en valoir la peine.
Les DTO ne sont pas un anti-pattern. Lorsque vous envoyez des données à travers le fil (par exemple, à une page web dans un appel Ajax), vous voulez être sûr que vous conservez la bande passante en envoyant uniquement des données que la destination utilisera. En outre, il est souvent pratique pour la couche de présentation d'avoir les données dans un format légèrement différent d'un objet métier natif.
Je sais que c'est une question orientée Java, mais dans les langages. net, les types anonymes, la sérialisation et LINQ permettent aux Dto d'être construit à la volée, ce qui réduit la configuration et les frais généraux de les utiliser.
DTO un AntiPattern dans EJB 3.0 dit:
La nature lourde de L'entité Haricots dans les spécifications EJB avant EJB 3.0, a abouti à l'utilisation de modèles de conception comme le transfert de données Les objets (DTO). Dto est devenu le objets légers (qui devraient avoir été les haricots entité eux-mêmes dans la première place), utilisé pour envoyer le les données à travers les niveaux... maintenant EJB 3.0 spec rend le modèle Entity bean identique comme objet Java Ancien (POJO). Avec ce nouveau modèle POJO, vous ne serez pas plus besoin de créer un DTO pour chaque entité ou un ensemble d'entités... Si vous souhaitez envoyer les entités EJB 3.0 à travers le niveau faites les juste implémenter java. Io. Serialiazable
Je ne pense pas que les DTO soient un anti-motif en soi, mais il existe des antipatterns associés à L'utilisation des DTO. Bill Dudney se réfère à l'explosion DTO à titre d'exemple:
Http://www.softwaresummit.com/2003/speakers/DudneyJ2EEAntiPatterns.pdf
Il y a aussi un certain nombre d'abus de DTO mentionnés ici:
Http://anirudhvyas.com/root/2008/04/19/abuses-of-dto-pattern-in-java-world/
Ils proviennent de systèmes à trois niveaux (généralement utiliser EJB comme technologie) comme moyen de transmettre des données entre les niveaux. La plupart des systèmes Java modernes basés sur des frameworks tels que Spring adoptent une vue simplifiée alternative en utilisant des POJOs comme objets de domaine (souvent annotés avec JPA, etc...) dans un seul niveau... L'utilisation de DTO est ici inutile.
Les puristes oo diraient que DTO est anti-pattern car les objets deviennent des représentations de table de données au lieu d'objets de domaine réels.
Certains considèrent les DTO comme un anti-modèle en raison de leurs abus possibles. Ils sont souvent utilisés quand ils ne devraient pas être/n'ont pas besoin d'être.
Cet article décrit vaguement certains abus.
Si vous construisez un système distribué, alors les DTO ne sont certainement pas un modèle anti. Tout le monde ne se développera pas dans ce sens, mais si vous avez une application sociale ouverte (par exemple), tout fonctionne hors JavaScript.
Il affichera une charge de données sur votre API. Ceci est ensuite désérialisé en une forme d'objet, généralement un objet Dto / Request. Cela peut ensuite être validé pour s'assurer que les données saisies sont correctes avant d'être converties en objet modèle.
À mon avis, il est considéré comme un anti-modèle parce qu'il est mal utilisé. Si vous n'êtes pas construire un système distribué, les chances sont que vous n'en avez pas besoin.
DTO devient une nécessité et non un ANTI-PATTERN lorsque tous vos objets de domaine chargent les objets associés avec impatience.
Si vous ne créez pas de DTO, vous aurez des objets transférés inutiles de votre couche métier vers votre couche client/web.
Pour limiter les frais généraux dans ce cas, transférez plutôt les DTO.
L'intention d'un objet de transfert de données est de stocker des données provenant de différentes sources, puis de les transférer dans une base de données (ou façade distante) à la fois.
Cependant, le modèle DTO viole le principe de responsabilité unique , puisque le DTO stocke non seulement des données, mais les transfère également depuis ou vers la base de données/façade.
La nécessité de séparer les objets de données des objets métier n'est pas un antipattern, car il est probablement nécessaire de séparer la couche de base de données de toute façon.
Au lieu de DTO, vous devez utiliser les modèles D'agrégat et de référentiel, qui séparent la collection d'objets (Aggregate) et le transfert de données (Repository).
Pour transférer un groupe d'objets, vous pouvez utiliser le modèle Unité de travail , qui contient un ensemble de référentiels et un contexte de transaction; afin de transférer chaque objet dans l'agrégat séparément dans la transaction.
Je pense que les gens veulent dire que cela pourrait être un anti-pattern si vous implémentez tous les objets distants en tant que DTO. un DTO est simplement juste un ensemble d'attributs et si vous avez de gros objets, vous transférerez toujours tous les attributs même si vous n'en avez pas besoin ou ne les utilisez pas. Dans ce dernier cas, préférez utiliser un modèle Proxy.
La question ne doit pas être "pourquoi", mais "lorsque".
Définitivement c'est anti-pattern quand seul le résultat de son utilisation est un coût plus élevé -temps d'exécution ou de maintenance. J'ai travaillé sur des projets ayant des centaines de DTO identiques aux classes d'entités de base de données. Chaque fois que vous vouliez ajouter un seul champ, vous ajoutez un id comme quatre fois-à DTO, à entity, à la conversion de DTO en classes ou entités de domaine, la conversion inverse,... Vous avez oublié certains des endroits et des données incompatible.
C'est Pas anti-pattern quand vous avez vraiment besoin d'une représentation différente des classes de domaine - plus plate, plus riche, plus étroite,...
Personnellement, je commence par la classe de domaine et le passe, avec une vérification appropriée aux bons endroits. Je peux annoter et / ou ajouter des classes "helper" pour faire des mappages, à la base de données, aux formats de sérialisation comme JSON ou XML ... Je peux toujours diviser une classe à deux si je ressens le besoin.
C'est à propos de votre point de vue - je préférez regarder un objet de domaine comme un seul objet jouant différents rôles, au lieu de plusieurs objets créés les uns des autres. Si le seul rôle d'un objet est de transporter des données, alors C'est DTO.