Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Interprétation idéale de l'architecture MVC
Quelle est la meilleure approche ?

Le , par alatox

0PARTAGES

0  0 
Bonjour,

J'essaye de depuis quelques temps de comprendre le principe du MVC.
J'ai donc suivi des tutoriaux sur le net et me suis documenté.

Ce message s'adresse donc aux personnes ayant lu le livre "Swing" de la collection "les cahiers du programmeur" publié chez eyrolles.

p167 est présenté un diagramme de classe MVC dit idéal puis p175 un diagramme de classes simplifié.

Quel aurait été le diagramme de classe MVC idéal avec les classes HomeController, FurnitureController, et CatalogController (p175)?

Par ailleurs, il me semble avoir compris que les MVC permettait de rendre les couches indépendantes et j'ai du mal saisir pourquoi c'est au contrôleur d'instancier la vue, pouvez vous m'expliquer ?. (J'aurais plutôt la vue être instanciée ailleurs et passée au contrôleur ensuite)

Ensuite, si je désirais rajouter une base de données. Les interrogations à cette dernière interviendraient dans quelle entité du MVC ? (Je ferais ça dans le modèle mais je vois bien aussi le contrôleur le faire et ensuite le passer au modèle qui ne serait finalement plus qu'un cache)

Merci d'avance pour vos réponses.

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de bouye
Rédacteur/Modérateur https://www.developpez.com
Le 28/08/2009 à 1:06
Je ne peux pas trop parler du livre (pas lu) mais de ce qui est implemente en standard dans l'API par Sun :

le petit probleme dans le MVC c'est que souvent (dans la plupart des implementations) le controlleur est en fait fortement dependant de l'aspect physique de la vue puisque c'est entre autre la vue qui sait quelles sont les zones qui peuvent ou non reagir a la souris.
Ensuite de maniere plus gobale il ne faut pas se leurrer : il serait utopique de croire qu'on peut mettre m'importe quel type de controleur sur n'importe quelle vue et que tout se mette a fonctionner correctement comme par magie.

Typiquement un controleur pour bouton ne fonctionnera que sur une vue pour bouton.

Swing n'est pas vraiment MVC en fait mais plutot M et VC : la plupart des composants simples/unitaires disposent d'un modele (M) et d'une UIdelegate (VC, l'UIdelegate est a la fois une vue et un controleur). On a plutot une dependance :

composant -> M
composant -> VC

En JavaFX c'est encore different : un Control (l'equivalent du composant) dispose d'une Skin (V) qui elle-meme a un Behavior (C). De part la nature meme du language il n'y a pas trop de classe dediee au modele bien que rien n'empeche d'en creer une et que par certains cotes on peut considerer que le controle lui-meme est un modele.
Dans les implementation actuelles c'est le controle reference la skin et la skin qui reference le behavior en gros on a une dependance plutot dans le style :

controle->V->C
0  0 
Avatar de alatox
Membre du Club https://www.developpez.com
Le 28/08/2009 à 13:43
Merci pour ta réponse mais ma question ne portait pas sur la façon dont le M-VC est implémenté dans Swing.

Si sur un petit exemple avec un modèle (une liste de beans par exemple), il me semble être capable d'implémenter un MVC, je peine à voir son fonctionnement dans une application dans laquelle des objets graphiques "seraient construits" à partir de vues, ou même dans le cas où des Vues en utiliseraient d'autres pour "se construire".

Un exemple, imaginons une application (Swing comme par hasard) avec un menu d'administration qui doit permettre d'accéder aux tables d'une base de données et de les gérer. Les modèles sont donc des Listes de beans que l'on contrôle.

Pour un "modèle liste", je considère que la vue est composée
- du tableau qui permet de voir l'état de la table, accompagnée de boutons d'ajouts et de modification (pour fixer les idées, mettons le tout dans un "panneau".
- de la fenêtre qui s'ouvre lorsque l'on appuie sur ajouter ou modifier une ligne (pré-remplie si on appuie sur modifier).

Lorsque j'appuie sur ajouter, le contrôleur se charge de rendre visible la fenêtre d'ajout. Je saisis des informations dans cette vue. Après un appuie sur "valider" dans la fenêtre de création, le contrôleur demande au "modèle liste" de changer, ce dernier change et notifie la vue, et cette dernière se met à jour.

Maintenant si dans la fenêtre d'ajout j'ai à gérer des listes (des nouveaux modèles) qui remplissent une combo box. J'ai donc un contrôleur pour cette liste et la vue associée à ce modèle est une combo box, qui pourra être consultée et utilisée par le "modèle liste" ou éventuellement remplie à l'aide d'un bouton d'ajout à côté.

J'ai donc besoin de la vue combo box pour construire la vue d'un "modèle Liste". Ce faisant j'ai deux contrôleurs à déclarer

Voici mes questions :

Est ce que le premier contrôleur doit instancier le second contrôleur (celui de la combo box) puis utiliser une méthode de type getVue() pour passer la "vue combox box" à la "vue Liste". Si tel est le cas il est impossible pour le contrôleur Liste (qui aurait été chargé de faire un new VueListe(modeleListe)) de faire le new VueListe(modeleListe) sans avoir à instancier un "controleur combo box", et l'on doit rajouter des méthodes pour transmettre des composant à la vue Liste.

Vous voyez mon problème ? la stratégie proposée parait-t-elle viable ? Existe-t-il une solution ?
0  0 
Avatar de PanicKernel
Membre régulier https://www.developpez.com
Le 31/08/2009 à 9:57
C'est vrai que je trouve dommage d'avoir un getVue() sur un controleur.

Je pense que le mieux c'est de pouvoir instancier une vue sans préciser son controleur, c'est à dire que la vue doit-être faiblement couplée sur le controleur.

Pour se faire, mes vues n'appellent jamais le controleur directement après un évt utilisateur (ie click sur un bouton de validation par ex). Au lieu de cela, je déclare une interface listener pour ma vue qui déclare ce type d'évt et c'est le controleur qui s'y abonne et implémente ces traitement via un addListener() sur la vue. Contrairement à Swing ce sont des évts orientés métier (par ex un evt validerEditionPersonne associé au click sur le bouton Ok).

Dans ton cas, tu pourrais donc instancier ta vue directement avec son modèle puis tu prends le controleur que tu souhaites et il s'abonne sur cette vue.
0  0 
Avatar de alatox
Membre du Club https://www.developpez.com
Le 31/08/2009 à 11:02
Justement je trouve aussi dommage d'avoir à faire un getVue(), mais dans le livre que je cite, il passe d'un mvc dit "idéal" à un mvc "simplifié", mais dans les deux cas ils disposent de méthodes getView() ou getVue(). Ces méthodes renvoient dans le premier cas un élèment de type "IView" i.e un interface View disposant d'une méthode display(). Et dans le second cas, un JComponent. Par ailleurs, les contrôleurs sont imbriqués, i.e c'est à dire que des contrôleurs "plus généraux" en instancie d'autres et disposent de méthodes "getController()".

D'après le livre ces types sont assez généraux pour ne pas perdre l'intérêt du MVC. Je rappelle que de la façon dont il fonctionne, chaque contrôleur instancie la vue. La vue ne connaît le contrôleur qu'au travers d'une interface ce qui évite d'avoir à déclarer les contrôleurs comme des écouteurss de vues, ce qui peut se comprendre car une vue est associée à un contrôleur contrairement dans le cas du modèle qui peut prévenir plusieurs écouteurs de ces changements.

Je voudrais juste mettre l'accent sur le fait qu'il ne faut pas confondre le mvc2 ou le contrôleur est central et le mvc classique dans lequel la vue à par exemple accès en lecture au modèle.
0  0 
Avatar de PanicKernel
Membre régulier https://www.developpez.com
Le 31/08/2009 à 11:17
Je suis d'accord avec ce que tu dis. Ma façon de faire est inspirée de Swing et revient finalement au même que de créer une interface controleur.

Cependant c'est cette histoire de getView() est gênante car comme le controleur instancie la vue, il est fortement couplé à une implémentation de sa vue et donc il n'est pas possible de le faire travailler avec une autre implémentation.
0  0 
Avatar de alatox
Membre du Club https://www.developpez.com
Le 31/08/2009 à 13:05
PanicKernel: Donc si tu as des composants graphiques ou des vues construits à partir d'autres vues comment tu t'y prends ?
0  0 
Avatar de benwit
Rédacteur https://www.developpez.com
Le 31/08/2009 à 14:08
Dans le cas où ton getView() renvoit une interface IView, tu as bien un découplage non ?

Certes, le contrôleur dit bien qu'il a besoin d'une IView et d'une méthode display() (et en ce sens, il y a un couplage ! comment pourrais il en être autrement ?)
Ensuite, le fait d'utiliser une interface permet d'avoir différentes implémentations de la vue.
Il faut que l'instanciation de la vue soit déléguée à une fabrique ou faire de l'injection de dépendance.
0  0 
Avatar de PanicKernel
Membre régulier https://www.developpez.com
Le 31/08/2009 à 14:12
Dans les cas que j'ai rencontré, il fallait afficher un arbre de sélection à gauche et une vue à droite de détail sur le noeud sélectionné.

Ce que je fais c'est que mon arbre et mon formulaire (vues métiers) sont à l'intérieure d'une vue composite technique qui ne génère aucun d'évt vers un controleur, ni ne connait de modèle. Elle se fait injecter les deux sous-vues "métiers" par constructeur (ou setter, au choix) depuis le controleur. Seules les deux vues métiers vont travailler avec un modèle et un controleur (via les évts qu'elles génèrent comme j'en ai parlé tout à l'heure).

C'est clair ?
0  0 
Avatar de PanicKernel
Membre régulier https://www.developpez.com
Le 31/08/2009 à 14:15
Citation Envoyé par benwit Voir le message
Dans le cas où ton getView() renvoit une interface IView, tu as bien un découplage non ?

Certes, le contrôleur dit bien qu'il a besoin d'une IView et d'une méthode display() (et en ce sens, il y a un couplage ! comment pourrais il en être autrement ?)
Ensuite, le fait d'utiliser une interface permet d'avoir différentes implémentations de la vue.
Il faut que l'instanciation de la vue soit déléguée à une fabrique ou faire de l'injection de dépendance.
En fait, je fais de l'injection via un addListener(), le listener étant le controleur.
0  0 
Avatar de alatox
Membre du Club https://www.developpez.com
Le 31/08/2009 à 16:31
Donc si je vous suis bien l'imbrication de contrôleurs et l'utilisation de méthodes getIView() ne rompt pas le principe du MVC.

Donc la stratégie suivante : un contrôleur plus global qui en instancierait d'autres (ces derniers feraient un "new IView()") et utiliserait leur méthode getIView() pour construire sa vue (getController1().getIView() et getController2.getIView()) parait correcte ?

S'il me semble comprendre qu'il faut déclarer une interface IControleurModel pour chaque vue d'un modèle (afin d'encapsuler les méthodes de changements du modèle) faut-t-il alors une seule classe IView implémentée par toute les Vues ou une "interface IViewModel" pour chaque modèle et implémentée par une classe concrète "ViewModel" ?

Une autre question, est-t-il possible (dans la logique mvc car tout est possible ), d'avoir un contrôleur associé à une vue sans modèle (je pense que non)? Pourquoi car je pense à un contrôleur de l'application qui instancierait d'autres contrôleusr.

Concrètement, dans l'exemple que je cite plus haut avec "la vue Liste"
et la vue "Combo Box". Le "contrôleur Liste" instancierait le "contrôleur Combo Box" et par un "getControllerComboBox().getView()" le "contrôleur Liste" "construirait" sa vue.
0  0