IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Struts 1 Java Discussion :

[Struts]demande de conseils au niveau décomposition MVC


Sujet :

Struts 1 Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2003
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 105
    Par défaut [Struts]demande de conseils au niveau décomposition MVC
    Bonjour à tous, je me pose une petite question concernant un developpement "propre" d'un appli struts.

    Pour avoir un modèle MVC (ou plutot MV2C) propre, j'avais pensé à faire ceci:
    Utiliser des classes métiers:
    par exemple une classe utilisateur qui accèdent à une base de donnée et récupèrent les informations précises.
    Les beans: qui contiennent les seules infos necessaires, avec uniquement des méthodes get et set. (ex: userBean)
    Les struts actions: un action pour se logger instanciera un Utilisateur (à partir de son login récupéré dans un bean reçu par exemple), récupèrera les infos necessaires sur ce dernier (par appel à ses méthodes) et crée un bean de retour userBean avec ses informations qu'il renvoie aux vues.
    Les vues:
    ex: une vue qui utilise le bean userBean et affiche les résultats attendus.

    En gros jaurrais ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Utilisateur extends ClasseMetier{
    public Utilisateur ("login"){
     //connexion à la bd et recup des infos
    }
    public getNom(){rreturn nom);
    }
     et à partir de ma struts action faire:
    String login = (String)actionForm.get("login");
    Utilisateur monUtilisateur= new monUtilisateur(login);
    userBean  ubean= new userBean ();
    ubean.setNom(monUtilisateur.getNom());
    session.setAttribute("userInfo", ubean);
    return (mapping.findForward("success"));
    Donc j'aimerais avoir votre avis sur cette méthode, étant encore novice en la matière.

    Par contre, je me demande si on crée le bean de retour (userBean) dans la struts action (en faisiant par exemple userBean.setNom(Utilisateur.getNom()) ) ou dans la classe métier, en utilisant par exemple une méthode renvoyant l bean créé:
    ex:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Utilisateur extends ClasseMetier{
    public userBean getuserBean(){
     userBean bean = new UserBean();
      bean.setNom(this.nom); 
    bean.setInfo...(this.nom); 
      return bean;
    }
    }
     et à partir de ma struts action faire:
    String login = (String)actionForm.get("login");
    Utilisateur monUtilisateur= new monUtilisateur(login);
    userBean  ubean= monUtilisateur.getUserBean);
    session.setAttribute("userInfo", ubean);
    return (mapping.findForward("success"));
    Si javais directement créé le bean userBean à partir de mes struts Actions (donc en faisant les requetes SQL à partir des Actions), je ne pense pas que ça soit très propre (redondance de code pour acceder aux données, grosses modifs à faire en cas de changement de bas ou autre).

    edit: on dit toujours de moi que je ne susi jamais assez clair,alors n'hésitez pas à demander plus de précisions

  2. #2
    Expert confirmé
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Par défaut
    Bonjour.
    pour l'effort et le respect du MVC !

    Sinon, en ce qui concerne la couche métier, ce que dont tu parles est le pattern DTO/DAO :
    - DTO : Data Transfer Object en gros un POJO (getXXX et setXXX) et qui comme son nom l'indique sert à transférer les données entre les couches de l'application
    - DAO : Data Access Object : des classes qui manipulent les DTO, càd qu'ils les chargent de la BD, qu'ils les persistent, les suppriment, etc.


    en gros, tous tes DAOs auront en commun cette structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public Interface GenericDao<T, ID>{
      public List<T> findAll();
      public T findById(ID id);
      public void delete(T entity);
      public void update(T entity);
      public T add(T entity);
    }
    Et tu peux ajouter d'autres méthodes au besoin.
    Dans ton cas par exemple, on peut définir le DTO du User comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    public class User {
      private Long id;
      private String login;
      private String pwd;
     
      //Les getters + les setters
     
    }
    et ton UserDao :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    public class UserDao implements GenericDao<User, Long> {
      //implémentes les méthodes du généric Dao
     
      //Tu peux ajouter cette méthode
      public List<User> findByExample(User u){
      ..."SELECT * FROM user WHERE login=u.getLogin() AND pwd=u.getPwd()"...
      }
    }
    La méthode qu'on a ajouté, findByExample, peut servir dans l'action LoginAction : ici un exemple d'execute()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    User u = new User();
    u.setLogin(form.getLogin());
    u.setPwd(form.getPwd());
    List<User> res = (new UserDao()).findByExample(u);
    if(res.size()==0)
      return mapping.findForward("failure");
    else
      return mapping.findForward("success");

    Bref, j'espère que tu a compris le principe !

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2003
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 105
    Par défaut
    je vois à peu près le truc oui.

    Donc si j'ai bien compris jaurrais 4 types de classes:

    1)Les actionForm étant les bean contenant les données transmises par les formulaires et utilisés par mes struts Action

    2)Les struts Action qui prennent ce quil ya dans les bean et créent les DTO
    A partir de ça on renvoie vers une vue qui utilise ces DTO (si seulement besoin d'afficher les infos ransmises par formulaire) ou demandent aux DAO de creer les DTO à partir des données fournies par les beans

    3) les DTO: qui servent à communiquer de façon interne en transportant les infos

    4) les DAO: classes métiers qui accèdent à la base et retourne les infos sous forme de DTO.

    Est-ce que je me trompe?

    Autre question conernant les DAO: si j'ai bien compris, tu peux demander à un DAO de créer un DTO à partir d'un DTO partiel? je m'explique. Tu a un DTO user DTO contenant login, passwd, nom, ...
    Je peux très bien remplir un DTO (depuis laction struts) avec seulement son login et password et demander au DAO de me retourner un DTO complet (contenant toutes les infos user) ou le cas échéant un DTO vide si l'utilisateur na pas été trouvé


    jespere ne pas avoir tout compris de travers XD

  4. #4
    Membre Expert
    Avatar de azerr
    Homme Profil pro
    Ingénieur Etude JEE/Eclipse RCP
    Inscrit en
    Avril 2006
    Messages
    942
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Etude JEE/Eclipse RCP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2006
    Messages : 942
    Par défaut
    Bonjour johan_b,
    je me permets de m'initier dans votre conversation,
    car je pense qu'il est aussi important d'avoir une couche Service
    qui est entre les actions et les DAO.

    J'ai fait un schema pour mon projet gestcv :
    http://gestcv.sourceforge.net/fr/architecture.html

    La couche service gere le metier de ton application (ex : un utilisateur doit avoir un login unique lors de sa creation). Les actions font appel a la couche service.

    Si tu n'as pas cette couche les regles metiers tu devra les mettre soit :

    * dans ton action. Probleme : d'autres application (ou d'autres actions) qui voudront avoir la meme regle de gestion devront dupliquer cette regle.

    *dans ta DAO. Probleme : imagines que tu developpe une DAO qui cree un utilisateur et que tu mettes ta regles metiers dans ta DAO (login unique). Au cours du developpement, tu as besoin de creer pour un cas particulier un utilisateur qui aurrait le meme login. Tu ne peux plus reutiliser ta DAO. Si tu gere ton metier dans la couche Service. Tu aurras deux services differents qui appeleront la meme DAO.

    La couche service a pour but aussi d'assembler les donnees retournes par les DAO pour construire une DTO (complexe ou non) (Attention de ne pas executer 40 milles requetes pour construire une DTO).

    Dans mon schema, je parle aussi de Bean Persistent, car j'utilise Hibernate et Spring, mais bon je ne vais pas t'embrouiller plus.

    J'espere que ca pourra t'aider. Si tu as le temps tu peux lire gestcv, car j'ai tente d'expliquer au mieux mon choix d'architecture.

    Angelo

  5. #5
    Expert confirmé
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Par défaut
    Bonjour.
    Rassures toi : t'as pas tout compris à travers, mais ill y'a juste ton 2ième point qui divague un peu ...
    Citation Envoyé par johan_b
    2)Les struts Action qui prennent ce quil ya dans les bean et créent les DTO
    A partir de ça on renvoie vers une vue qui utilise ces DTO (si seulement besoin d'afficher les infos ransmises par formulaire) ou demandent aux DAO de creer les DTO à partir des données fournies par les beans
    Ca jamais ! les vues n'ont jamais jamais jamais accès aux DAOs ! C'est l'esprit même du MVC !

    Donc, pour résumer, tu as 5 types de classes (en gros) :
    1-Les DTOs : support de données
    2-Les DAOs : gestion des DTOs en général avec la BD.
    3-Les autres classes de la couche métier

    4-Les ActionForm de Struts, une sorte de remake des DTOs, mais en moins de détail : par exemple, UserForm (login, pwd) tandis que UserDTO (login, pwd, nom, age, etc...). Les ActionForm sont en principe une représentation des formulaires des pages JSP.(Mais à mon avis c'est l'un des gros défauts de Struts, car on aurait pu utiliser directement les DTOs comme dans JSF)
    5- Les Actions de Struts qui en gros effectuent 4 opérations dans la méthode execute :
    1. Récupérer l'ActionForm associé à l'action et le convertir en DTO
    2. Faire appel à la couche métier (aux DAOs et autres)
    3. Stocker les résultats (des DTOs en général) dans le/les scopes de ton choix pour qu'ils soient disponibles aux vues.
    4. Forwarder selon les résultats retournés par le Model.
    Donc, les vues comme je l'ai dit n'ont jamais accès aux DAOs ! il récupèrent juste des DTOs que les actions stockent dans la session ou le request.

    En ce qui concerne ta question sur les classes partiellement replies, etc. ça peut se faire, mais de préférence si tu utilises Hibernate comme couche de persistence (les Criterion et les Example font tout le sale boulot), mais avec JDBC seulement, ce serait vraiment un casse gueule ! Une telle opération se révèle surtout utile pour des recherches.

    Pour l'exemple de connexion, tu peux aussi procéder comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class UserDao implements GenericDao<User, Long> {
      //implémentes les méthodes du généric Dao
     
      //Tu peux ajouter cette méthode
      public User validate(String aLogin, String aPwd){
      ..."SELECT * FROM user WHERE login=aLogin AND pwd=aPwd"...
      }
    }
    et dans la méthode execute() de LoginAction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    User u = (new UserDao()).validate(form.getLogin()
    , form.getPwd()
    );
    if(u==null)
      return mapping.findForward("failure");
    else {
      request.getSession.setAttribute("connectedUser", u);
      return mapping.findForward("success");
    }
    On évite comme ça le passage par la méthode findByExample.
    Veuilles STP noter le fait que j'ai mis le DTO du User dans la session (3ième étape de Action.execute), comme ça, dans tes vues (pages JSP) tu peux affficher le nom de l'utilisateur connecté comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <bean:write name="connectedUser" property="name" />
    Un dernière chose : c'est du MVC mais fortement imprégné de ma vision des choses, donc ce ne sont pas les paroles du dieu, tu peux en tirer ce qui te plait et y ajouter de ton crue !

  6. #6
    Membre Expert
    Avatar de azerr
    Homme Profil pro
    Ingénieur Etude JEE/Eclipse RCP
    Inscrit en
    Avril 2006
    Messages
    942
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Etude JEE/Eclipse RCP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2006
    Messages : 942
    Par défaut
    Bonjour Modjo,
    je partage tout ce que tu viens de dire.

    (Mais à mon avis c'est l'un des gros défauts de Struts, car on aurait pu utiliser directement les DTOs comme dans JSF)
    Oui je suis d'accord pour la version Struts 1.x. La version Struts 2.x qui est base sur Webwork a supprime le concept d'ActionForm. Maintenant on peut utiliser sa DTO (d'apres ce que j'ai pu lire) dans son Action.

    Un sujet qu'on oublie souvent et qui super chaud a gerer correctement est la gestion des connections (ouverture/fermeture connection, debut/fin transaction).

    Je n'aime pas appeler directement la DAO dans l'action car cela signifie que

    * soit l'Action Struts doit gerer les connections. Le probleme avec cette solution et que l'on cree un fort couplage a la base de donnee dans l'Action. Si on veut changer de type d'acces (ex : WebService) on ne peut pas.

    * soit la DAO gere ces connections (ouverture/fermeture), ce qui signifie que l'on ne peut pas enchainer plusieurs DAO en utilisant la meme connection (ce qui est genant pour la gestion des transactions).

    La couche service permet :

    * gerer le metier de l'entreprise.
    * gerer les ouverture/fermeture de connections. Autrement dit a l'appel d'un e method d'un service on ouvre une connection, a la fin de la methode on ferme la connection.

    Le jour ou l'on souhaite changer de type d'acces aux donnees, seule la couche service est impactee.

    L'enchainement des DAO (pour gerer une transaction) peut ensuite s'effectuer dans un service. Mais souvent on creer un service (ex: creerUtilisateur) , puis un autre (creerRole) et on souhaite enchainer l'appel de ces deux services a la suite. Mais ceci n'est pas possible car chaque method ouvre et ferme les connections. Avec l'AOP de Spring, on peut gerer ce cas. Je ne vais pas m'etaler sur le sujet, mais avec l'AOP de Spring, la problematique des gestions de connections est un vrai bonheur.

    J'ai tente de l'expliquer ici :
    http://gestcv.sourceforge.net/fr/arc...re/spring.html


    Angelo

  7. #7
    Expert confirmé
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Par défaut
    Pardon azerr, j'avais pas vu ton post (tu l'avais envoyé pendant que je rédigais le mien).

    pour la couche Services ! J'avoue que j'y avais jamais pensé ! Je fesais tout un tas de maneuvres (sales pour la plupart) pour y arriver.

    pour le fait d'évoquer le sujet des ouverture/fermetude des transactions mais surtout des sessions Hibernate : C'est un sujet super explosif, et tout programmeur ayant jonglé avec Hibernate dans une application web décente doit surement avoir de très mauvaises souvenirs sur les objets détachés et les lazy fetch Exceptions !

    Je ne suis pas sur que ce post soit le bon endroit pour en discuter (on ne veut tout de même pas embrouiller johan_b ).

    Je te propose alors de créer un nouveau post sur le sujet Hibernate dans une application web) à moins bien sur que ce ne soit déja fait !

Discussions similaires

  1. Stage demande de conseils : Support niveau 3
    Par max8774 dans le forum Stages
    Réponses: 0
    Dernier message: 21/12/2012, 19h10
  2. [Struts_Tiles VS CSS] Demande de Conseils
    Par sylvain_neus dans le forum Struts 1
    Réponses: 4
    Dernier message: 16/04/2004, 10h12
  3. [sqlbaseserver]demande de conseils/aides pour requêtes
    Par GéniuS77 dans le forum Langage SQL
    Réponses: 14
    Dernier message: 18/03/2004, 17h27
  4. demande de conseil
    Par stephane eyskens dans le forum EDI/Outils
    Réponses: 2
    Dernier message: 25/09/2003, 14h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo