J'ai récemment entendu des gens dire que objets de transfert de données (DTO) sont un anti-modèle .
Pourquoi? Quelles sont les alternatives?
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.
Ceci la 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-modèle. Lorsque vous envoyez des données via le câble (par exemple, vers une page Web dans un appel Ajax), vous voulez être sûr de conserver la bande passante en n'envoyant que 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 construits à la volée, ce qui réduit la configuration et les frais généraux liés à leur utilisation.
DTO un AntiPattern dans EJB 3. dit:
La nature lourde des Entity Beans dans les spécifications EJB avant EJB 3.0, a entraîné l'utilisation de modèles de conception tels que les objets de transfert de données (DTO). Les DTO sont devenus les objets légers (qui auraient dû être les beans entité eux-mêmes en premier lieu), utilisés pour envoyer les données à travers les niveaux ... maintenant la spécification EJB 3.0 rend le modèle de bean Entity identique à Plain old Java objet (POJO). Avec ce nouveau modèle POJO, vous n'aurez plus besoin de créer un DTO pour chaque entité ou pour un ensemble d'entités ... Si vous souhaitez envoyer les entités EJB 3.0 à travers le niveau, faites-les implémentez simplement Java.io.Serialiazable
Je ne pense pas que les DTO soient un anti-modèle en soi, mais il existe des anti-modèles associés à l'utilisation des DTO. Bill Dudney fait référence à l'explosion du DTO comme exemple:
http://www.softwaresummit.com/2003/speakers/DudneyJ2EEAntiPatterns.pdf
Il y a également un certain nombre d'abus des DTO mentionnés ici:
http://anirudhvyas.com/root/2008/04/19/abuses-of-dto-pattern-in-Java-world/
Ils sont dus à des systèmes à trois niveaux (utilisant généralement EJB comme technologie) comme moyen de transmettre des données entre les niveaux. La plupart des temps modernes Java basés sur des frameworks tels que Spring prennent une vue simplifiée alternative en utilisant des POJO comme objets de domaine (souvent annotés avec JPA etc ...) dans un seul niveau ... L'utilisation de Les DTO ici ne sont pas nécessaires.
Les puristes OO diraient que le DTO est anti-modèle car les objets deviennent des représentations de table de données au lieu d'objets de domaine réel.
Certains considèrent les DTO comme un anti-modèle en raison de leurs éventuels abus. Ils sont souvent utilisés alors qu'ils ne devraient pas être/n'ont pas besoin de l'être.
Cet article décrit vaguement certains abus.
Si vous construisez un système distribué, les DTO ne sont certainement pas un anti modèle. Tout le monde ne se développera pas dans ce sens, mais si vous avez (par exemple) une application Open Social fonctionnant toutes avec JavaScript.
Il publiera une charge de données sur votre API. Il est ensuite désérialisé en une certaine forme d'objet, généralement un objet DTO/Request. Cela peut ensuite être validé pour s'assurer que les données entrées sont correctes avant d'être converties en objet de modèle.
À mon avis, c'est considéré comme un anti-modèle parce qu'il est mal utilisé. Si vous ne construisez pas un système distribué, il est probable que vous n'en ayez pas besoin.
Le DTO devient une nécessité et non un ANTI-PATTERN lorsque tous vos objets de domaine chargent les objets associés avec EAGERly.
Si vous ne faites 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 Data Transfer Object est de stocker des données de différentes sources, puis de les transférer dans une base de données (ou Remote Facade ) à la fois.
Cependant, le modèle DTO viole le principe de responsabilité unique, car le DTO stocke non seulement les données, mais les transfère également depuis ou à 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 contre-modèle, car il est probablement nécessaire de séparer la couche de base de données de toute façon.
Au lieu des DTO, vous devez utiliser les modèles d'agrégat et de référentiel, qui séparent la collection d'objets ( agrégat ) et le transfert de données ( référentiel ).
Pour transférer un groupe d'objets, vous pouvez utiliser le modèle nit Of Work , 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.
La question ne devrait pas être "pourquoi", mais "quand".
Définitivement, c'est anti-modèle lorsque seul le résultat de son utilisation est plus coûteux - exécution ou 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 annoncez ajouter un identifiant comme quatre fois - au DTO, à l'entité, à la conversion du DTO en classes ou entités de domaine, la conversion inverse, ... Vous avez oublié certains des endroits et des données obtenus inconsistant.
C'est pas anti-modèle lorsque vous avez vraiment besoin d'une représentation différente des classes de domaine - plus plat, plus riche, plus étroit, ...
Personnellement, je commence par la classe de domaine et je la transmets, avec une vérification appropriée aux bons endroits. Je peux annoter et/ou ajouter des classes "d'aide" pour faire des mappages, des bases de données, des formats de sérialisation comme JSON ou XML ... Je peux toujours diviser une classe en deux si j'en ressens le besoin.
Il s'agit de votre point de vue - je préfère 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.
Je pense que les gens veulent dire que cela pourrait être un anti-modèle si vous implémentez tous les objets distants en tant que DTO. Un DTO est simplement un ensemble d'attributs et si vous avez de gros objets, vous transférez 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 de proxy.