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] Précisions


Sujet :

MVC

  1. #1
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 330
    Par défaut [MVC] Précisions
    Salut,

    J'aimerais avoir une précision sur l'implémentation correcte de la relation entre Vue et Controlleur dans l'approche MVC (Modèle-Vue-Contrôleur). La plupart des références bibliographiques que j'ai trouvé disent en gros que la vue transmet des évènements utilisateur au contrôleur qui ensuite se charge de les interpréter vis à vis du modèle.

    J'aimerais savoir s'il y a une bonne pratique de conception qui précise où situer l'interface d'échange de ces évènements utilisateur.

    Par exemple si j'ai un slider qui règle un volume sonore.

    Je peux :

    1- faire un controlleur avec une méthode setVolume(insigned int volume) et une vue qui détecte le déplacement du curseur et qui appelle controlleur.setVolume(slider.pos).

    ou bien

    2- faire un controlleur avec une méthode notifySliderChanged(SliderId id) et une vue qui détecte le déplacement du curseur et qui appelle controlleur.notifySliderChanged(mySliderId). Le controlleur fait alors le rapprochement (mySliderId <-> identifiant du curseur de volume), demande au slider sa nouvelle position et applique le volume.

    Quelle est la bonne approche ? Y en a t-il d'autres ?
    Merci pour vos conseils et réactions.

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 89
    Par défaut
    Salut,

    De ma maigre expérience sur MVC, je dirais que l'approche la plus "orientée" MVC serait la deuxième.

    A priori, la vue de doit pas avoir de notions sur ce qu'elle représente.
    Dans ton exemple, la vue ne devrait pas avoir de notion de volume.

    Le principe de MVC est de pouvoir changer l'une de ses trois parties (modèle, vue et controleur) de façon transparente pour les deux autres. Donc il faut toujours se demander ce qu'il se passerait si on changeait l'une des parties.

    Par exemple (d'un intérêt limité a priori, je l'admet ), avec ta première proposition, si un jour tu décides de ne plus gérer le volume mais la vitesse de lecture, tu devras modifier à la fois le controleur et la vue.
    Le controleur puisque c'est lui qui doit gérer la logique de l'application, et la vue, puisqu'elle implémentait déjà la gestion du slider comme étant un volume et non une vitesse.

    Je ne sais pas si je suis très clair, mais n'hésite pas à demander plus de détails sur les points restés obscurs.


    Je rajouterais un petit détail sur ta deuxième proposition. Elle implique que le controleur interroge la vue sur l'état du slider, et je ne pense pas que ce soit son role.
    Ici il serait plus simple de rajouter un paramètre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    controller.notifySliderChanged(mySliderId, cursorPosition)
    J'espère avoir pu t'aider. Je te donne un lien sur lequel je me repose souvent lorsque j'ai un doute à propos de MVC, mais peut être l'as-tu déjà parcouru lors de tes recherches (en anglais):
    http://java.sun.com/blueprints/patte...-detailed.html

  3. #3
    Expert confirmé
    Avatar de Baptiste Wicht
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    7 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2005
    Messages : 7 431
    Par défaut
    Comme l'a dit tristan_m, ta deuxième proposition a un gros problème, elle implique que le controlleur doive aller interroger un élément graphique. Alors qu'il faudrait avoir le moins de code possible en relation avec une quelconque interface graphique. Plus tu as du code dépendant d'un framework graphique, plus tu auras de peine ensuite à changer l'interface graphique par exemple passer de Swing à SWT.

    Donc la deuxième proposition est bonne, mais avec le changement que tristan_m y a ajouté. Maitenant qu'on a fait ce changement, la première proposition est presque la même que la deuxième.

  4. #4
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 330
    Par défaut
    Merci à tous les deux.

    Effectivement dans la deuxième approche, le fait que le contrôleur aille chercher des infos dans la vue me perturbait quelque peu. Avec la modification proposée que la vue transmette tous les paramètres utiles au contrôlleur ainsi que l'identifiant de l'élément graphique à l'origine de l'évènement c'est effectivement moins perturbant.
    Cela dit ça ne supprime pas totalement le fait que le contrôlleur doit avoir une connaissance de la représentation graphique (en effet il doit savoir quel changement associer à un changement sur SliderId...donc quelque part son implémentation dépend de la représentation graphique).

    Tout mon problème c'est qu'ils doivent forcément échanger quelque chose et je ne sais pas où situer l'interface :
    - soit le contrôleur impose son interface mais alors la vue a une notion de ce qu'elle représente.
    - soit la vue impose son interface mais alors le contrôleur dépend de la représentation graphique.

    J'aimerais avoir des arguments pour pouvoir trancher entre les deux ou bien trouver une troisième voie.

  5. #5
    Expert confirmé
    Avatar de Baptiste Wicht
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    7 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2005
    Messages : 7 431
    Par défaut
    Le contrôleur a bien sûr une notion de la vue, c'est sûr, il faut bien qu'il connaisse la vue pour l'ouvrir, la fermer, ...

    Une chose que tu peux faire pour le rendre encore moins dépendant de la vue, c'est créer une interface Vue qui contiendrait des méthodes close et open et d'autres méthodes si le contrôleur a besoin d'effectuer d'autres mises à jour sur la vue. Ensuite, il suffit que ta classe d'interface graphique implémente cette interface et le controleur n'a plus qu'à utiliser cette interface pour intéragir sur l'interface graphique. Donc en cas de changement d'interface graphique, il ne reste qu'une seule ligne à modifier dans le controleur.

    En plus, il n'a pas besoin de la représentation graphique de l'interface, il ne devrait justement pas en avoir pour être encore plus indépendant. Si tu utiliser un sliderId, ca doit correspondre à quelque chose dans le controlleur mais tu n'as pas besoin de savoir à quoi ca correspond du coté de la vue. Personnellement, j'utiliserais plutot la méthode setVolume, ainsi tu n'as de problème à associer quelque chose et en plus, c'est tout de même plus clair comme méthode.

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 89
    Par défaut
    Bonjour,

    Effectivement il y a malgré tout une dépendance quelque part. On ne peut pas remplacer la vue d'un lecteur multimedia par celle d'un jeu vidéo par exemple. D'ou l'importance, comme le signale wichtounet, de créer des interfaces pour les vues et les controleurs.

    Pour la question du lieu où gérer la dépendance vue - controleur, mon avis n'est pas vraiment tranché, mais je pense qu'il faut se pencher encore une fois sur les modifications possibles de controleurs ou de vues.
    En gros, si tu as de nombreux controleurs différents (resp. vues différentes) il sera préférable de gérer la dépendance dans les controleurs (resp. dans les vues).

    Je m'explique :
    1)Si tu as beaucoup de controleurs, c'est que ton appli peut passer dans de multiples états différents, et donc que la réaction face aux même événements de la vue risque d'être différente (un bouton play qui passe en bouton pause par exemple). Il est alors plus adéquate de donner un identifiant au bouton, et de laisser le controleur s'occuper de son implémentation.
    2)Si par contre tu as plusieurs vues différentes (mode texte, mode 2d, mode 3d par exemple), alors il vaudra peut être mieux mettre cette dépendance dans les vues et passer par des méthodes type controller.volumeChanged() etc...

    NB: même si concrètement ça ne change strictement rien, le nom 'setVolume' me gène un peu puisque ce n'est pas le controleur qui modifie la valeur mais le modèle.


    Après il y a encore les deux cas particuliers où :
    3) il y a à la fois beaucoup de controleurs et beaucoup de vues, et
    4) il y a une seule vue et un seul controleur

    Dans le cas 3, il faut peut être envisager d'insérer un objet entre la vue et le controleur qui associerait un id à une méthode controleur (voir le design pattern mediateur peut etre?).

    Pour le cas 4, il faut d'abord prendre en compte les évolutions possibles ou envisagées, pour voir si tu ne te retrouveras pas à l'avenir dans un des 3 cas précédents.
    Sinon (MVC est il alors nécessaire?), je pencherais finalement aussi du côté des méthodes controller.volumeChanged() appelées par la vue. C'est plus simple à implémenter, puisque ne nécessitant pas de table d'association 'idBouton<->action' ou de switch massif dans le controleur. (Dans l'idée, 'volume' fait ici référence au nom du slider et non au volume 'réel' représenté dans le modèle)

    En espérant t'avoir éclairé un peu.

  7. #7
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Par défaut
    Si je peux me permettre une remarque: l'utilisation du M(MVC)C.

    Cela consiste a séparer le MVC "graphique" (valeur 0-100% / slider / evenements) et le MVC "metier" (Player / Volume / Variation).

    Pourquoi cette séparation ? Et bien parceque généralement on a peu de controle sur le fonctionnement du MVC "graphique". Généralement ce n'est meme pas un vrai MVC, mais plutot un Form/Action ( Boucle de message, gestion evenementielle, ... ).

    Nom : m(mvc)c.png
Affichages : 81
Taille : 8,7 Ko
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

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

Discussions similaires

  1. architecture MVC - précisions
    Par djmic dans le forum Langage
    Réponses: 11
    Dernier message: 29/05/2015, 08h25
  2. Précisions sur Desing Pattern MVC
    Par totojava dans le forum Débuter
    Réponses: 12
    Dernier message: 28/04/2011, 19h36
  3. Précision à propos de ASP.Net MVC 2
    Par CARNIBAL dans le forum ASP.NET MVC
    Réponses: 15
    Dernier message: 19/05/2010, 13h18
  4. Réponses: 1
    Dernier message: 28/10/2009, 14h08
  5. [débutant] [MVC] précisions
    Par dahtah dans le forum MVC
    Réponses: 2
    Dernier message: 14/08/2007, 17h14

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