2008-10-03 5 views
3

J'ai hérité d'une grande application Java qui utilise Struts, Spring et Hibernate. Les classes et les interfaces que je traite quotidiennement sont les suivantes: Struts Actions, Struts ActionForms, Objets de valeur, Interfaces de service et implémentations, Interfaces DAO et Implémentations, et Entités. Je suis assez clair sur le comment et le pourquoi de la plupart d'entre eux, sauf que je ne suis pas sûr de la bonne séparation des responsabilités entre les ActionForms, les objets de valeur, et les entités. Je devrais également mentionner que le modèle de domaine (c.-à-d. Toutes les entités) ne contient pas beaucoup (s'il y en a) de vraie logique métier. C'est essentiellement une application CRUD et la plupart de la logique réelle est dans la base de données (beurk!). Quoi qu'il en soit, je m'interroge sur plusieurs problèmes liés à Java:Comment utiliser correctement Struts ActionForms, Value Objects et Entities?

1) Il semble qu'il n'y ait pas beaucoup de différence entre les entités et les objets de valeur (VOs), et beaucoup de code doit être écrit pour transformer dans l'autre quand ils traversent la couche de service dans l'une ou l'autre direction (les actions de Struts ne traitent que des VO, les DAO ne traitent que des entités). Donc, les VO et les Entités semblent un peu redondants. Pourquoi les avoir tous les deux?

2) Où devrait aller le VO < -> Entity translation code? La couche de service, l'Entité, la VO?

3) Les VO sont placés directement dans ActionForms et directement liés aux étiquettes dans la JSP (par exemple). Est-ce une bonne pratique? Si non, quel est le design approprié?

4) Il n'est pas clair comment gérer correctement les dépendances de clés étrangères dans les objets de valeur. Par exemple, certains VO ont un champ de type qui, en termes de base de données, représente une relation de clé étrangère dans une table de types. Dans l'interface utilisateur, cela se traduit par un champ déroulant qui permet à l'utilisateur de choisir le type, OU une étiquette qui affiche simplement la représentation textuelle du type (en fonction de l'écran). Maintenant, le VO devrait-il avoir une propriété pour l'ID de type, la représentation textuelle du type, ou les deux? Qui est responsable de la traduction entre les deux, et quand?

5) Les VO ont un champ pour leur ID de base de données. Je pensais que les VO n'avaient pas d'identité? Qu'est-ce qui se passe avec ça? J'espère que ces questions sont assez génériques pour être d'intérêt général. Il semble que cela viendrait tout le temps dans ce type d'architecture.

Aussi, j'ai le soupçon que cette architecture est très lourde pour cette application, et si vous avez des suggestions sur un meilleur, allez-y. Mais je m'intéresse principalement à la réponse aux questions ci-dessus, car une architecture différente est un refactoring à long terme que je ne peux pas faire maintenant.

Répondre

3

1. Considérant la transformation DAO-VO; si cela est utile dépend de la façon dont Hibernate est utilisé. Si la totalité de la gestion des requêtes Web est dans une seule session Hibernate, vous ne devriez pas vraiment avoir besoin de VO séparées. Cependant, si votre couche DAO ouvre une session pour récupérer un objet et ferme la session avant d'avoir fini d'utiliser le DAO, vous pouvez rencontrer des problèmes avec les collections et les références à d'autres objets.

Il y a de fortes chances que ceux-ci soient paresseusement chargés, ce qui signifie que la session doit toujours être ouverte lors de la demande de ces propriétés. En bref, avant de commencer à abandonner ces VO, jetez un coup d'œil à vos transactions de base de données et à vos limites de session.

3. En ce qui concerne l'utilisation d'un VO dans un formulaire; si le VO correspond bien à la JSP je dirais pourquoi pas? Je suis soit impressionné que le modèle de données soit si proche du processus qu'il supporte, et un peu méfiant que la base de données n'a pas été normalisée (ce qui peut ou non poser des problèmes à l'avenir). Retournez à 1. Si vous utilisez des DAO avec un chargement différé et des collectes, souvenez-vous que la session de la base de données doit également inclure la phase JSP car le DAO sera lu dans cette phase.

  1. La couche de service doit avoir la possibilité de connaître les objets de base de données à modifier, et l'id est conçu pour cela. La couche de service devra récupérer le DAO de la base de données et écrire les champs de la VO dans le DAO, bien qu'il n'ait évidemment pas besoin de mettre à jour l'ID du DAO avec l'ID du VO :)

  2. vous avez besoin de la demande est l'id du champ de clé étrangère. Comme il vient du client, vous devriez probablement vérifier dans la logique métier si un objet avec un tel ID existe.

Selon que le VO accepte l'id de l'objet étranger ou nécessite un objet, vous devriez alors:

  • définir l'ID ou
  • obtenir l'objet étranger en tant que VO par id en utilisant la couche de service et le mettre dans votre VO et le stocker en utilisant la couche de service

votre couche d'affaires est responsable des traductions comme le service à la Vous ne traitez que la récupération et le stockage des objets. Et le texte ou l'identifiant ne sont pas des objets mais des identifiants des objets. La couche de service peut offrir des fonctions de recherche, mais elle ne devrait pas avoir besoin d'informations contextuelles.

Et si je lis bien votre question, vos VO se réfèrent à d'autres objets dans la base de données par ID. Dans ce cas, vous entrez l'identifiant.Si vous obtenez une chaîne du client, vous devez la rechercher dans la couche de gestion (en utilisant la couche de service) et placer l'ID de l'objet trouvé dans la VO. Ou, si aucun ID n'est trouvé, renvoyez un message d'erreur décent.

À titre de note de clôture; Ne touchez pas à la chose DAO-VO à moins de savoir ce que vous faites vraiment. Hibernate est un outil puissant et complexe qui est faussement facile à utiliser. Vous pouvez très facilement faire des erreurs et elles peuvent être très difficiles à trouver. Et les clients et les patrons ne semblent pas apprécier l'introduction de bugs dans les choses qui avaient l'habitude de travailler.

Par ailleurs; mon conservatisme dans la chose DAO-VO vient de la résolution de problèmes dus à des problèmes similaires dans les transitions EJB2 à Hibernate. Le diable est dans les détails, et changer la façon dont vous traitez la couche de données est un refactoring majeur, même si cela ressemble à un morceau de gâteau.

+0

Belle réponse, merci! – thvo

1

1) Pas besoin de VO et Entités séparées: certaines entreprises mandatent une telle structure pour leur projet. Cela peut avoir du sens dans un projet différent et donc il a été mandaté (je ne peux que deviner)

2) Couche de service: c'est la séparation naturelle de DAO et de la couche Action, non?

3) Il ne fait pas mal mais les objets de valeur sont liés aussi longtemps qu'ils ont été dûment validées avant envoyés à OTI

4) La couche de service doit être responsable de la traduction entre les deux. Pendant le chargement et le gain de temps

5) s'ils n'ont pas d'identité, alors comment éviteriez-vous la duplication?

J'espère que ces réponses laconiques ont aidé. Je vais essayer de revenir et donner une réponse plus tard plus tard.

0

Pour répondre à votre dernière partie, utilisez Spring MVC au lieu de Struts. Vous pouvez ensuite utiliser les mêmes objets de domaine sur toutes les couches: les classes qui se lient aux paramètres de formulaire sont également utilisées dans Hibernate et contiennent une véritable logique métier. Par exemple, dans une application que j'ai utilisée avec Spring MVC, j'avais une classe membre. Les formulaires de connexion, d'enregistrement, de modification de mot de passe et d'édition de profil étaient tous liés à cette classe. La classe avait également une cartographie d'hibernation et une bonne partie de la logique métier à l'intérieur (par exemple, pour un réseau social, une méthode "ajouter un ami").

+0

Dans un grand projet, vous ne pouvez pas simplement passer de Struts à Spring MVC. C'est un refactoring MAJEUR. J'ai à peu près besoin de faire de petits changements incrémentiels. – thvo

Questions connexes