Je travaille sur l'application RCP, je suis nouveau sur cette application.
Les beans Spring sont utilisés pour écrire la logique métier pour enregistrer/récupérer des entités.
Mais, au lieu d'envoyer des entités directement au client nous convertissons en DTO et de remplir le client. Lors de l'enregistrement, nous convertissons à nouveau DTO en entité et enregistrons.
Quel est l'avantage de ces conversions? Quelqu'un peut-il expliquer?
Chaque fois qu'un développeur demande "quel est l'intérêt de faire cela?", Ce qu'ils veulent vraiment dire, c'est "je ne vois aucun cas d'utilisation où cela offre un avantage". À cette fin, permettez-moi de vous montrer quelques exemples.
Tous les exemples seront basés sur ce modèle de données simple:
Une entité
Person
a cinq propriétés:Id, FirstName, LastName, Age, CityId
Et vous pouvez supposer que l'application utilise ces données de différentes manières (rapports, formulaires, popups, ...).
L'application entière existe déjà. Tout ce que je mentionne est une modification de la base de code existante. C'est important à retenir.
Exemple 1 - Modification de la structure de données sous-jacente - Sans DTO
Les exigences ont changé. L'âge de la personne doit être récupéré dynamiquement dans la base de données du gouvernement (supposons en fonction de son prénom et de son nom).
Comme vous n'avez plus besoin de stocker la valeur Age
localement, elle doit donc être supprimée de l'entité Person
. Il est important ici de se rendre compte que l'entité représente les données de la base de données, et rien de plus. Si ce n'est pas dans la base de données, ce n'est pas dans l'entité.
Lorsque vous récupérez l'âge du service Web du gouvernement, celui-ci sera stocké dans un autre objet (ou int).
Mais votre frontend affiche toujours un âge. Toutes les vues ont été configurées pour utiliser le Person.Age
propriété, qui n'existe plus. Un problème se présente: Toutes les vues qui font référence au Age
d'une personne doivent être corrigées.
Exemple 2 - Modification de la structure de données sous-jacente - Avec DTO
Dans l'ancien système, il existe également une entité PersonDTO
avec les cinq mêmes propriétés: Id, FirstName, LastName, Age, CityId
. Après avoir récupéré un Person
, la couche de service le convertit en un PersonDTO
, puis le renvoie.
Mais maintenant, les exigences ont changé. L'âge de la personne doit être récupéré dynamiquement dans la base de données du gouvernement (supposons en fonction de son prénom et de son nom).
Comme vous n'avez plus besoin de stocker la valeur Age
localement, elle doit donc être supprimée de l'entité Person
. Il est important ici de se rendre compte que l'entité représente les données de la base de données, et rien de plus. Si ce n'est pas dans la base de données, ce n'est pas dans l'entité.
Cependant, puisque vous avez un intermédiaire PersonDTO
, il est important de voir que cette classe peut garder la propriété Age
. La couche de service récupérera le Person
, le convertira en un PersonDTO
, elle récupérera également l'âge de la personne sur le service Web du gouvernement, stockera cette valeur dans PersonDTO.Age
, et passe cet objet.
La partie importante ici est que toute personne qui utilise la couche service ne voit pas de différence entre l'ancien et le nouveau système. Cela inclut votre frontend. Dans l'ancien système, il recevait un objet PersonDTO
complet. Et dans le nouveau système, il reçoit toujours un objet PersonDTO
complet. Les vues n'ont pas besoin d'être mises à jour.
C'est ce que nous voulons dire lorsque nous utilisons l'expression séparation des préoccupations: Il existe deux préoccupations différentes (stockage des données dans la base de données, présentation des données à l'interface) et elles ont besoin d'un type de données différent chacune. Même si ces deux types de données contiennent actuellement les mêmes données, cela pourrait changer à l'avenir.
Dans l'exemple donné, Age
est une différence entre les deux types de données: Person
(l'entité de base de données) n'a pas besoin d'un Age
, mais PersonDTO
(le type de données frontal) en a besoin.
En séparant les préoccupations (= création de types de données séparés) depuis le début, la base de code est beaucoup plus résistante aux modifications apportées au modèle de données.
Vous pourriez faire valoir qu'avoir un objet DTO, lorsqu'une nouvelle colonne est ajoutée à la base de données, signifie que vous devez effectuer un double travail, en ajoutant la propriété à la fois dans l'entité et dans le DTO. C'est techniquement correct. Il faut un peu d'effort supplémentaire pour maintenir deux classes au lieu d'une.
Cependant, vous devez comparer l'effort requis. Lorsqu'une ou plusieurs nouvelles colonnes sont ajoutées, copier/coller quelques propriétés ne prend pas autant de temps. Lorsque le modèle de données change structurellement, devoir changer le frontend, peut-être d'une manière qui ne cause que des bogues au moment de l'exécution (et non au moment de la compilation), demande beaucoup plus d'efforts et nécessite que le ou les développeurs partent à la recherche de bogues.
Je pourrais vous donner plus d'exemples mais le principe sera toujours le même.
Pour résumer
Person
)Name
. Mais ce n'est pas parce qu'ils ont tous une propriété Name
que nous devons les faire hériter d'une classe de base EntityWithName
partagée. Les différentes propriétés Name
n'ont aucune relation significative.Name
d'un morceau est renommé en Title
, ou une personne obtient un FirstName
et LastName
), ils vous ' Je vais devoir dépenser plus d'efforts pour annuler l'héritage dont vous n'aviez même pas besoin en premier lieu .En règle générale, pour envisager de séparer les préoccupations, pensez-y de cette façon:
Supposons que toutes les préoccupations (l'interface utilisateur, la base de données, la logique) soient gérées par une personne différente dans un emplacement différent. Ils ne peuvent communiquer que par email.
Dans une base de code bien séparée, une modification d'une préoccupation particulière ne devra être gérée que par une seule personne:
Si tous ces développeurs utilisaient la même entité Person
et qu'une modification mineure était apportée à l'entité, tout le monde devrait être impliqué dans le processus.
Mais en utilisant des classes de données distinctes pour chaque couche, ce problème n'est pas aussi répandu:
PersonDTO
valide, le développeur d'entreprise et d'interface utilisateur ne se soucie pas qu'il ait changé la façon dont les données sont stockées/récupérées.La phrase clé ici est car elle ne les affecte pas. La mise en œuvre d'une bonne séparation des préoccupations vise à minimiser les effets (et donc la participation) des autres parties.
Bien sûr, certains changements majeurs ne peuvent pas éviter d'inclure plus d'une personne, par exemple lorsqu'une entité entièrement nouvelle est ajoutée à la base de données. Mais ne sous-estimez pas le nombre de modifications mineures que vous devez effectuer pendant la durée de vie d'une application. Les changements majeurs sont une minorité numérique.