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

MVC Discussion :

[MVC]: le Contrôleur [DAO] et le Transfer Object.


Sujet :

MVC

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 90
    Par défaut [MVC]: le Contrôleur [DAO] et le Transfer Object.
    Bonjour à tous et toutes,

    J'ai une petite question qui me tracasse sérieusement sur la notion de Transfer Object en fait.
    Pour ceux qui ne connaissent pas (ou peut-être qui utilisent déjà cette notion sans connaître le nom), voici un lien explicite abordant la notion de Transfer Object:
    http://java.sun.com/blueprints/corej...essObject.html

    D'après ce que j'ai compris, le Transfer Object est un objet métier, que l'on souhaite transmettre d'une méthode à une autre.
    Ainsi, plutôt que de passer à une méthode toute une suite de paramètres représentant les valeurs des attributs d'un objet, et bien on lui passe juste l'objet lui-même pré-renseigné.
    Exemple appel de : setUser( ObjetUser) au lieu de setUser(login, passw, ...). Où ObjetUser est de type User, et possède déjà en interne les attributs: login,passw,... renseignés.
    Donc très pratique: notamment pas besoin de rajouter ou enlever des paramètres dans la signature de la méthode appelée (ici setUser()), en cas d'ajout ou suppression d'attributs à l'objet. Sans compter le risque d'erreurs (inversion de l'ordre des params,...) que le fait de passer plusieurs params comporte.


    Bref, voici, ma, mes questions:
    Dans le cadre du modèle MVC utilisant un contrôleur DAO (Data Access Object):
    - Lien ci-dessus +
    - Diagramme de séquence par exemple:
    http://www.developpez.net/forums/d63...onne-pratique/


    Peut-on utiliser une forme de Transfer Object entre IHM et Contrôleur IHM? Et/Ou entre Contrôleur IHM et Contrôleur DAO?
    En fait je voudrais savoir si c'est gênant que la classe -(ou même une fabrique
    pour cette classe)- du Transfer Object en question (Customer dans leur exemple) soit connue au niveau de l'IHM ou du Contrôleur IHM?


    Et plus précisément, avec l'exemple suivant:

    Au niveau de l'IHM: on est sur une Fiche de création de User.
    La personne qui saisit, renseigne à ce jour: le login, le passw puis valide.
    La validation sollicite le Contrôleur IHM qui sait alors qu'il doit venir récupérer
    les données User saisies.

    LAQUELLE DES 6 SOLUTIONS PRESENTEES ci-dessous VOUS SEMBLE LA PLUS CLEAN ???
    LAQUELLE voyez-vous le plus souvent?
    LAQUELLE utilisez-vous le plus souvent?


    (Ici mon Transfer Object est donc un objet User).


    //----------------------------------------------

    SOLUTION 1:
    -La classe IHM connaît carrément la Classe concrète User.
    -La classe contrôleurIHM connaît le type abstrait User.
    -->GROS INCONVENIENT: couplage de l'IHM avec 1 type concret du MODELE: type User.

    class IHM
    {
    //...
    void actionPerformed(...)
    {
    if (clickSurValid)
    this.controleurIHM.demande_addUser(); //Informe son ControleurIHM de la validation
    //...
    }

    //Renvoie l'intégralité de la saisie sous forme d'objet User.
    User getUser()
    {
    String login=this.widgetLogin.getvalue();
    String passw=this.widgetPassw.getvalue();

    //L'IHM connaît donc la classe CONCRETE User!!!
    User trsf_object=new User(login, passw); //<<<<<<< !!

    return(trsf_object);
    }
    //...
    }


    class controleurIHM
    {
    //...
    void demande_addUser() //Appelée suite à validation de la fiche User.
    {
    //Recup. sous forme d'Objet User, du User saisi.
    User trsf_object=this.vue.getUser();

    //Demande au Contrôleur DAO de créer la fiche pour le User décrit par trsf_object.
    this.controleurDAO.insertUser(trsf_object);
    }
    //...
    }

    //----------------------------------------------

    SOLUTION 2:
    -La classe IHM connaît une fabrique concrète de User, et aussi le type User abstrait .
    -La classe contrôleurIHM connaît le type abstrait User.
    -->GROS INCONVENIENT: couplage de l'IHM avec 1 type concret du MODELE: fabriqUser et 1 type abstrait: User.

    class IHM
    {
    //...
    void actionPerformed(...)
    {
    if (clickSurValid)
    this.controleurIHM.demande_addUser(); //Informe son ControleurIHM de la validation
    //...
    }

    //Renvoie l'intégralité de la saisie sous forme d'objet User.
    User getUser()
    {
    String login=this.widgetLogin.getvalue();
    String passw=this.widgetPassw.getvalue();

    //L'IHM connaît donc une fabrique concrete de User, et le type User abstrait
    fabriqUser fabriq=new fabriqUser();
    User trsf_object=fabriq.makeInstance(login, passw); //<<<<<< !!

    return(trsf_object);
    }
    //...
    }

    class controleurIHM
    {
    //...
    void demande_addUser() //Appelée suite à validation de la fiche User.
    {
    //Recup. sous forme d'Objet User, du User saisi.
    User trsf_object=this.vue.getUser();

    //Demande au Contrôleur DAO de créer la fiche pour le User décrit par trsf_object.
    this.controleurDAO.insertUser(trsf_object);
    }
    //...
    }


    //----------------------------------------------

    SOLUTION 3:
    -La classe IHM connaît le type abstrait de la fabrique de User, et aussi le type User abstrait.
    -La classe contrôleurIHM connaît le type User abstrait ET le type concret ou même abstrait de la fabrique de User.
    -->GROS INCONVENIENT: couplage de l'IHM avec 2 types abstraits du MODELE: User et fabriqUser.

    class IHM
    {
    //...
    void actionPerformed(...)
    {
    if (clickSurValid)
    this.controleurIHM.demande_addUser(); //Informe son ControleurIHM de la validation
    //...
    }

    //Renvoie l'intégralité de la saisie sous forme d'objet User.
    User getUser( fabriqUser fabriq ) //<<Reçoit une fabrique de User.
    {
    String login=this.widgetLogin.getvalue();
    String passw=this.widgetPassw.getvalue();

    //L'IHM connaît le type abstrait de la fabrique de User, et aussi le type User abstrait.
    User trsf_object=fabriq.makeInstance(login, passw); //<<<<<<

    return(trsf_object);
    }
    //...
    }


    class controleurIHM
    {
    //...
    void demande_addUser() //Appelée suite à validation de la fiche User.
    {

    //Recup. sous forme d'Objet User, du User saisi.
    //On peut imaginer que this.fabriqUser a passée en param. au constructeur du
    //contrôleur ou encore a été initialisé par un :
    // fabriqUser this.fabriqUser=this.controleurDAO.getFabriqUser();

    User trsf_object=this.vue.getUser( this.fabriqUser ); //<<<<<

    //Demande au Contrôleur DAO de créer la fiche pour le User décrit par trsf_object.
    this.controleurDAO.insertUser(trsf_object);
    }
    //...
    }


    //-------------------------------------------

    SOLUTION 4:
    -La classe IHM ne connaît pas le type User, ni même une fabrique de User.
    -La classe contrôleurIHM connaît la classe User concrète.
    -INCONVENIENTS:
    -->Si on rajoute n infos supplémentaires à saisir (Nom, Prenom,...) alors:
    ---->Ca fait n méthodes en plus à créer dans la classe IHM.
    ---->Ca fait n this.vue.getXXX() à faire en plus dans le contrôleur.
    ---->Donc au moins n risques d'erreurs , d'oublis en plus.
    -->GROS INCONVENIENT: couplage du Controleur IHM avec un type concret du MODELE: type User.

    class IHM
    {
    //...
    void actionPerformed(...)
    {
    if (clickSurValid)
    this.controleurIHM.demande_addUser(); //Informe son ControleurIHM de la validation
    //...
    }

    String getLogin()
    {
    return( this.widgetLogin.getvalue() );
    }

    String getPassw()
    {
    return( this.widgetPassw.getvalue() );
    }

    //...
    }


    class controleurIHM
    {
    //...
    void demande_addUser() //Appelée suite à validation de la fiche User.
    {

    //Interroge la vue champ de saisie par champ de saisie. <<<<<<<<<
    String login=this.vue.getLogin();
    String passw=this.vue.getPassw();


    //Mise sous forme d'Objet User des infos User saisies.
    User trsf_object=new User(login, passw); //<<<<<<<<<<<

    //Demande au Contrôleur DAO de créer la fiche pour le User décrit par trsf_object.
    this.controleurDAO.insertUser(trsf_object);
    }
    //...
    }


    //-------------------------------------------

    SOLUTION 5:
    -L'IHM ne connaît pas le type User, ni même une fabrique de User.
    -La classe contrôleurIHM connaît le type User abstrait ET le type concret ou même abstrait de la fabrique de User.
    -INCONVENIENTS:
    -->Si on rajoute n infos supplémentaires à saisir (Nom, Prenom,...) alors:
    ---->Ca fait n méthodes en plus à créer dans la classe IHM.
    ---->Ca fait n this.vue.getXXX() à faire en plus dans le contrôleur.
    ---->Donc au moins n risques d'erreurs , d'oublis en plus.
    -->Couplage du Controleur IHM avec un type (au mieux) abstrait du MODELE, à savoir: le type fabriqUser.

    class IHM
    {
    //...
    void actionPerformed(...)
    {
    if (clickSurValid)
    this.controleurIHM.demande_addUser(); //Informe son ControleurIHM de la validation
    //...
    }

    String getLogin()
    {
    return( this.widgetLogin.getvalue() );
    }

    String getPassw()
    {
    return( this.widgetPassw.getvalue() );
    }

    //...
    }


    class controleurIHM
    {
    //...
    void demande_addUser() //Appelée suite à validation de la fiche User.
    {

    //Interroge la vue champ de saisie par champ de saisie. <<<<<<<<<<<<<<<
    String login=this.vue.getLogin();
    String passw=this.vue.getPassw();


    //Mise sous forme d'Objet User des infos User saisies.
    //On peut imaginer que this.fabriqUser a passée en param. au constructeur du
    //contrôleur ou encore a été initialisé par un :
    // fabriqUser this.fabriqUser=this.controleurDAO.getFabriqUser();
    User trsf_object=this.fabriqUser.makeInstance(login, passw); //<<<<

    //Demande au Contrôleur DAO de créer la fiche pour le User décrit par trsf_object.
    this.controleurDAO.insertUser(trsf_object);
    }
    //...
    }


    //-------------------------------------------

    SOLUTION 6:
    ( PAS de Transfer Object dans cette solution ).
    -La classe IHM ne connaît pas le type User, ni même une fabrique de User.
    -La classe contrôleurIHM ne connaît pas le type User, ni même une fabrique de User.
    -INCONVENIENTS:
    -->Si on rajoute n infos supplémentaires à saisir (Nom, Prenom,...) alors:
    ---->Ca fait n méthodes en plus à créer dans la classe IHM.
    ---->Ca fait n this.vue.getXXX() à faire en plus dans le contrôleur.
    ---->Donc au moins n risques d'erreurs , d'oublis en plus.


    class IHM

    {
    //...
    void actionPerformed(...)
    {
    if (clickSurValid)
    this.controleurIHM.demande_addUser(); //Informe son ControleurIHM de la validation
    //...
    }

    String getLogin()
    {
    return( this.widgetLogin.getvalue() );
    }

    String getPassw()
    {
    return( this.widgetPassw.getvalue() );
    }

    //...
    }


    class controleurIHM
    {
    //...
    void demande_addUser() //Appelée suite à validation de la fiche User.
    {

    //Interroge la vue champ de saisie par champ de saisie. <<<<<<<<<<<<<<<
    String login=this.vue.getLogin();
    String passw=this.vue.getPassw();


    //Demande au Contrôleur DAO de créer la fiche pour le User saisi.
    this.controleurDAO.insertUser(login, passw);
    }
    //...
    }

    //-------------------------------------

    La SOLUTION 6 est celle qui nécessite le moins de couplage, cependant elle n'est pas sans les inconvénients mentionnés. De plus, La signature de la méthode insertUser() du ContrôleurDAO reste du coup dépendante du NOMBRE d'attributs d'un User! (Sans compter qu'il ne faudra alors pas se planter sur l'ordre de transmission de ces paramètres!!), ceci donc du fait que cette solution n'utilise pas de Transfer Object.

    Personnellement, je sens bien la SOLUTION 3 car elle n'a pas les inconvénients de la SOLUTION 6 d'une part, et d'un point de vue couplage ça reste du couplage qu'avec du type abstrait (User et fabriqUser). Pour le reste je n'ai pas assez d'expérience du MVC pour pouvoir donner mon avis. Ce qui me gêne malgré tout dans cette SOLUTION 3 c'est que l'IHM
    elle-même sache des choses (même abstraites) sur le MODELE... ceci dit l' l'IHM est censée représenter le MODELE alors... ?


    Et vous, :
    LAQUELLE DES 6 SOLUTIONS VOUS SEMBLE LA PLUS CLEAN ???
    LAQUELLE voyez-vous le plus souvent?
    LAQUELLE utilisez-vous le plus souvent?




    MERCI BEAUCOUP de partager votre expérience sur ces points.
    MILLE MERCIs pour vos avis et critiques.

  2. #2
    Membre Expert
    Avatar de Patriarch24
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    1 047
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 047

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 90
    Par défaut
    Merci Patriarch24,


    Il me semble que le lien que tu proposes est bien pour ceux qui connaissent déjà bien le sujet et souhaitent approfondir.
    J'avoue que je suis loin de comprendre tout ce qui apparaît dans ce lien,
    (sachant que pour ma part je débute en JAVA, et donc pour moi un EJB c'est une notion très vague: et à vrai dire je voudrais pouvoir m'en passer dans un premier temps ).
    Donc en ce qui me concerne, je ne suis pas plus avancé car tout ceci semble
    bien lourd par rapport à ce que je voudrais juste savoir pour du MVC.

    Si tu as des avis plus personnels et plus simples et directs sur le sujet,
    et en particulier mes interrogations, je suis carrément preneur .


    Quoiqu'il en soit, merci encore Patriarch24 pour ton intervention.

  4. #4
    Membre extrêmement actif

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Par défaut
    Une petite remarque (car j'ai lu entre les lignes ) dans tes solutions tu mets en évidence que la Vue à une visibilité sur le modèle (dans toutes tes solutions quasiment) hors le principe pilier du MVC c'est la strict séparation entre le modèle et la vue (d'où l'utilisation d'un controleur).

    En bref, le modèle ne doit jamais connaître la vue et la vue ne doit pas faire d'opérations directement sur le modèle. D'après ce que je comprends de tes exemples tu veux construire un objet métiers dans la vue pour le passer au controleur ? Si j'ai bien compris alors cela ne me semble pas bon du tout.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 90
    Par défaut
    Bonjour hegros,

    Ben oui , je sais bien c'est pour ça que je pose les questions!?
    En fait à partir de la SOLUTION 4: la Vue ne sait rien du MODELE
    (hormis qu'elle est Observatrice de celui-ci quand même).

    Et moi OUI ce que je voudrais c'est pouvoir manipuler des objets User
    même au niveau de la Vue pour éviter de me trimballer tout un tas d'attributs (login, passw, ,nom, prenom,...) lorsque le Contrôleur veut par exemple récupérer la saisie des infos User effectuée.

    Moi, ma méthode getUser() de la Vue me plaît bien, mais je sais, je sens que qqch n'est pas CLEAN là-dedans: il doit bien y avoir une façon astucieuse et clean de procéder pour que la Vue puisse manipuler des entités User en tant qu'objet !??



  6. #6
    Membre Expert
    Avatar de Patriarch24
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    1 047
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 047
    Par défaut
    Pour moi, il n'existe pas beaucoup de types de DTO : les objets de contexte "descendant", et les objets résultats "montant". Je m'explique :
    - lorsque les données "descendent" vers la couche DAO, on transmet un contexte (des paramètres si vous préférez)
    - lorsque les données circulent dans l'autre sens, il s'agit généralement d'objets métiers (les entités).

    Généralement, les DTO sont utilisés pour les applications distribuées, là où il n'est pas possible ou acceptable de faire passer des objets lourds, ou d'appeler plusieurs méthodes distantes pour récupérer des données corrélées. Ils peuvent aussi être utilisés pour ne passer qu'une partie d'une entité.

    Dans ton cas, User n'est pas un DTO, mais une entité (destiné à être enregistrée en DB). La solution que je te propose est la suivante : le contrôleur crée un objet contexte (une map généralement) avec les données (login passwd), passe cet objet à la couche métier (pattern "application service") via une méthode "saveUser" par exemple, qui s'occupera de la création de l'entité et de sa sauvegarde via le DAO.

  7. #7
    Membre confirmé
    Inscrit en
    Septembre 2008
    Messages
    234
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 234
    Par défaut
    Citation Envoyé par rp37000 Voir le message
    (sachant que pour ma part je débute en JAVA, et donc pour moi un EJB c'est une notion très vague: et à vrai dire je voudrais pouvoir m'en passer dans un premier temps ).
    Salut,

    Sortant d'une formation récente, je dirais que c'est assez vague pour moi aussi. Mais d'après ce que j'ai compris, les EJB (stateless et message driven) forment la "colle" qui va permettre interagir avec les business objects derrière. C'est une manière de standardiser l'approche à la réalisation d'une application serveur.

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 90
    Par défaut
    Bonjour Jimalexp,

    Merci de ton intervention et les infos que tu communiques.

    Pour ma part , les EJB je voudrais éviter.... (notion vaguement croisée)

    Pour résoudre mon problème, je voudrais juste en fait utiliser des notions de POO de base, que je connais:
    Interfaces, etc...

    D'où la Solution à laquelle je songe juste ci-dessus...
    enfin si c'est pas trop négativement critiqué...

  9. #9
    Membre confirmé
    Inscrit en
    Septembre 2008
    Messages
    234
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 234
    Par défaut
    Je comprends . De toute façon les EJB c'est une manière de présenter les choses alors qu'il est tout à fait possible de faire autrement.

    Malheureusement, je connais encore mal le pattern MVC (je sais juste qu'on découple un système en trois parties selon un interface utilisateur), mais ca va venir.

    Par contre, il y a une chose qui me frappe dans le titre. Le Data Access Object implique t-il qu'il y a des accès à distance ? Si oui, seuls les transfers de valeurs sont possibles. J'ai donc un peu de mal à comprendre le schéma "Participants and Responsibilities" sur le lien qui a été donné. Car il serais impossible d' "envoyer" un objet à un client si l'accès n'est pas local.

    Il va falloir que je creuse ca parcequ'on a utilisé les DAO a plusieurs reprises durant la formation :p

    En ce qui concerne ton problème et que j'en tire vaguement, je suis toujours d'avis qu'il faut concevoir ses applications (objets et patterns) de sorte qu'il y a le moins d'interdépendances possibles et ce histoire de réduire le travail de modification/maintenance au stricte minimum. On devrais donc se limiter à se référer à un objet de type commun mais ne pas faire d'appels directes aux méthodes et plutôt passer par des classes interfaces ou des opérations élémentaires (si les nombre de paramètres est variables, garder les paramètres qui ne changent pas et envoyer le reste dans un bloc qui pourrais être parsé). Le mieux c'est d'imaginer qu'on est à plusieurs à travailler sur un projet et d'établir des contraintes en fonction de cela.

    P.S: Je suis d'accord avec Patriarch24 dans le sens où des objets de types entités serais une bonne idée (objet + attributs, setters, getters et rien d'autre).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. model mvc et la DAO
    Par nashouille dans le forum C#
    Réponses: 1
    Dernier message: 13/05/2011, 20h24
  2. Data Transfer Object
    Par ngomsi dans le forum C#
    Réponses: 1
    Dernier message: 29/01/2008, 10h44
  3. [Spring MVC] Formulaires, contrôleurs.. besoin d'aide.
    Par Invité dans le forum Spring Web
    Réponses: 6
    Dernier message: 13/07/2007, 16h25
  4. Champ de texte et MVC (modèle vue contrôleur)
    Par three minute hero dans le forum Windows
    Réponses: 1
    Dernier message: 22/02/2007, 11h04
  5. Site web MVC : Comment gérer le contrôleur frontal ?
    Par HALOMOTO dans le forum Langage
    Réponses: 5
    Dernier message: 10/10/2006, 17h59

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