web-dev-qa-db-fra.com

DTO ou objet de modèle de domaine dans la couche de vue?

Je sais que c'est probablement une question séculaire, mais quelle est la meilleure pratique? Utilisation d'un objet de modèle de domaine dans toutes les couches de votre application, et même la liaison de valeurs directement sur celles-ci sur le JSP (j'utilise JSF). Vous pouvez également convertir un objet de modèle de domaine en un DTO dans la couche DAO ou Service et envoyer un DTO léger à la couche de présentation.

On m'a dit que l'utilisation de DTO n'avait aucun sens, car des modifications apportées à la base de données entraîneraient des modifications pour tous vos DTO, alors que l'utilisation des objets de modèle partout nécessiterait simplement des modifications de l'objet de modèle affecté. Cependant, la facilité d'utilisation et la légèreté des DTO semblent l'emporter sur cela.

Je dois noter que mon application utilise les objets de modèle Hibernate ET utilise ses propres objets de modèle créés sur mesure (ce qui signifie qu'ils ne sont liés à aucune session de base de données, toujours détachés). L'un des scénarios ci-dessus est-il plus avantageux pour un modèle d'objet de modèle strict? Utiliser Hibernate a été un énorme PITA en ce qui concerne des choses telles que les exceptions d'initialisation différée.

J'édite cette question dans l'espoir de faire avancer la discussion (je ne sais pas si je le fais bien):

Le problème que j'ai avec les objets de modèle est qu'ils ne sont pas du tout flexibles. Un commentaire ci-dessous indique que l'application doit être conçue pour que les objets du modèle puissent être utilisés dans toutes les couches. Pourquoi? Si un utilisateur veut une fonctionnalité ridicule, je suis censé lui dire "cela ne fonctionnera pas avec les objets du modèle"?

Simplement et simplement, il y a des moments où les objets de modèle ne fonctionnent pas. Vous pouvez avoir:

public class Teacher {
    List<Student> students;
    [tons of other Teacher-related fields]
}
public class Student {
    double gpa;
   [tons of other Student-related fields]
}

mais peut-être que vous n'avez pas besoin de toutes ces informations. Vous avez simplement besoin du nom de famille de l'enseignant, du nombre d'élèves qu'il enseigne cette année et de la moyenne cumulative moyenne pour tous les élèves. Que feriez-vous dans ce cas? Récupérer les informations complètes sur l'enseignant et les relations avec les étudiants, puis votre code sera comptabilisé dans la liste des étudiants, puis calculera la moyenne totale de tous les gpas à l'intérieur? Cela semble nécessiter plus d'efforts que la simple création d'un DTO avec 'String lastName', 'int numStudents' et 'double combineGpa;

Cela peut sembler comme si ma décision était prise à ce sujet, mais je n’ai pas encore travaillé dans une application où les objets de modèle peuvent être utilisés de manière parfaitement propre dans chaque cas. Les applications réelles du monde réel avec des demandes d'utilisateurs inhabituelles ne fonctionnent tout simplement pas de cette façon.

49
sma

Cela dépend vraiment de la complexité de votre application. Le mélange d’objets de domaine dans la couche de vue a deux implications possibles:

  1. Vous serez tenté de modifier votre objet de domaine pour l'adapter à la couche de vue.
  2. Votre couche View contiendra une complexité supplémentaire due à une incompatibilité entre ce que vos objets de domaine offrent et ce dont votre vue a réellement besoin. Vous ne pourrez peut-être pas contourner cette complexité, mais cela n'appartient probablement pas à la couche Vue.

Si vos objets de domaine sont simples et que vos vues sont peu nombreuses, ignorer les DTO pourrait être la solution la plus simple. 

D'autre part, si votre modèle de domaine est susceptible d'évoluer et de devenir complexe et si vos vues sont susceptibles d'être nombreuses et variées, disposer d'objets spécifiques à une vue peut être une bonne idée. Dans le monde MVC, l'utilisation de ViewModels est courante et a beaucoup de sens pour moi.

33
srmark

Un autre vote pour les objets de domaine. En ce qui concerne Domain Driven Design, le modèle de domaine est le roi et doit être utilisé dans la mesure du possible. L'application doit être conçue de manière à ce que la plupart des couches (couche Infrastructure) puissent utiliser des objets de domaine.

Je pense que les DTO ne sont utiles que lorsque les objets doivent être sérialisés. S'il n'y a pas de transfert sur le réseau ou dans une architecture incompatible, je ne les utiliserais pas. Le modèle DTO est utile pour conserver la sérialisation en dehors de l'objet de domaine. Considérant que l’interaction UI/Domaine n’a pas besoin de sérialisation, restez simple et utilisez les objets réels.

8
Igor Zevaka

Je pense qu'avoir du DTO n'est généralement pas un anti-modèle. De nombreux utilisateurs et systèmes les utilisent. L'avantage que vous obtenez est la couche de vue découplée qui peut être conçue et modularisée indépendamment du modèle de domaine. Bien que je convienne que vous devriez utiliser des objets de domaine dans la mesure du possible, il existe des scénarios dans lesquels vous pouvez rencontrer des problèmes lorsque vous associez la couche de vue directement au modèle de domaine.

J'ai fait de bonnes expériences avec un modèle de vue qui englobe uniquement les objets de domaine et leur délègue la plupart des opérations. Cette opération permet de découpler la vue et le calque de domaine, permet une composition flexible des objets de domaine et ne nécessite toujours pas beaucoup de travail car les IDE prennent en charge modèle de délégation.

7
bennidi

À mon avis, l’utilisation d’objets de modèle de domaine dans chaque couche ne pose aucun problème. Vous avez dit que vous n'avez pas besoin de toutes les informations. Lorsque vous vous trouvez dans vos JSP, utilisez uniquement les données dont vous avez besoin. Personne ne vous oblige à aller chercher chaque propriété. Vous avez également déclaré que vous deviez effectuer des calculs liés aux propriétés de l'objet pour obtenir GPA, le nombre d'étudiants, etc. Vous avez 3 options: créer des propriétés synthétiques dans votre objet de modèle de domaine qui renvoient les bonnes données pour vous, bien emballées. Nice et soigné; effectuez les calculs dans la couche de contrôleur ou dans la couche service et exposez-les à travers les accesseurs appropriés; ou gérer tout cela dans votre JSP. Vous devez extraire/compiler/écarter les données de toute façon, alors pourquoi ajouter plus de complexité avec un DTO.

De plus, avec chaque DTO, vous créez un.) Une classe supplémentaire que vous devez maintenant gérer, et b.) À AU MOINS 1 méthode supplémentaire quelque part dans une classe qui construit et remplit le DTO (DAO, méthode d'usine, etc.) . Plus de maintenance = développeur mécontent 6 mois plus tard.

Donc, il y a mes arguments contre les DTO. Je les utilise, mais seulement dans certains scénarios, comme lorsque j'ai vraiment besoin d'optimiser la vitesse et/ou l'utilisation de la mémoire, et que le coût d'hydratation d'un objet de modèle de domaine complet est beaucoup trop élevé. Les services Web sont un bon exemple du moment où je préfère utiliser des DTO.

2
Aquarelle

Scénarios où l’envoi d’objets de domaine sont problématiques:

  1. vous aurez peut-être besoin d'informations agrégées ou d'autres types de «champs calculés» envoyés à la couche d'interface utilisateur (dans l'exemple Flex/GWT) et vous ne souhaitez pas déranger l'objet de domaine
  2. vous pouvez rencontrer un besoin de sérialisation du graphe d'objet cyclique (dans votre exemple, si l'étudiant avait une relation de liste), certains protocoles ont des problèmes avec cela
  3. Hibernate LazyInitializationException lors de l'utilisation des sérialiseurs d'infrastructure (blazeDS pour le sérialiseur flex/GWT)

Je ne suis pas sûr que ce soit une réponse claire dans ces circonstances

2
Al1998

Le comportement d'une classe ou ses méthodes internes ne doivent pas être exposés à des couches non concernées par leur comportement. Transférer des données, pas un comportement. Utilisez des objets de domaine dans le domaine. Le Web n'est pas un domaine contrôlé, et les développeurs d'interface utilisateur ne doivent pas nécessairement se préoccuper du comportement du domaine, mais uniquement des données.

Le domaine doit être encapsulé et protégé de toute modification par une personne qui n'est pas concernée par la santé du domaine.

Fuite de comportement n'est pas la meilleure habitude.

S'il s'agit d'un petit projet, construisez-le également avec les principes corrects. De cette façon, nous gardons toujours à l'esprit pourquoi nous faisons ce que nous faisons et pas seulement comment.

0
Ilan Y