Cours 6
Cours 6
l'architecture modèle-vue-contrôleur :
une composition de 3 design patterns
(composite + observateur + stratégie)
(ce cours présente l'architecture MVC depuis le point de vue des designs patterns et des principes de conception objet,
il fait volontairement peu référence à la programmation d'interfaces graphiques déjà présentée dans le cours IHM)
Motivation
MODELE
(logique applicative)
gère les données
VUE et les fonctionnalités
(IHM) du domaine considéré
saisit
les requêtes
(demandes
de l'utilisateur)
et affiche
les résultats
Utilisateur
CONTROLEUR
interprète les requêtes
en utilisant le MODELE,
ou la VUE
L'utilisateur peut :
●
entrer/modifier les coordonnées du point
L'application doit :
●
afficher les coordonnées du point
●
afficher la distance du point à l'origine
Point
VUE MODELE
(logique
(IHM) applicative)
gère lagère les données
saisie
deset les fonctionnalités
requêtes
du demandés
(services domaine considéré
par l'utilisateur) CONTROLEUR
et l'affichage
interprète les requêtes
Utilisateur des résultats
en utilisant la partie métier,
ou la VUE si la requête la concerne
… // VUE
SaisirPoint()
SaisirPoint()correspond
correspondààune
unerequête
requête(demande)
(demande)
dede l'utilisateur, requête proposée parlalavue
l'utilisateur, requête proposée par vue
public void saisirPoint()
{
instructions
instructionss'adressant
s'adressant ààlalavue
vue
float unX = [Link]() ; qui gère les interactions avec
l'interprétation
l'interprétation qui gère les interactions avec
de float unY = [Link]() ; l'utilisateur.
delalarequête
requête: : Ici
l'utilisateur.
relève
relèvedudu Ici demandeles
demande lescoordonnées
coordonnées
contrôleur [Link](unX, unY); pour le Point courant.
pour le Point courant.
contrôleur
} instruction
instructions'adressant
s'adressantau
aumodèle
modèle
pour
pour affecter les coordonnéessaisies
affecter les coordonnées saisies
... au
auPoint
Pointcourant
courant
} (aucune
(aucuneinteraction
interactionavec
avecl'utilisateur)
l'utilisateur)
menu
menuaffiché
affichéquand
quandon on
active la vue
active la vue ::
attend
attend lechoix
le choixde del'utilisateur
l'utilisateur
(les
(leschoix
choixcorrespondent
correspondentààdes des
requêtes prédéfinies)
requêtes prédéfinies)
// CONTROLEUR
...
public void gererSaisirPoint()
{ lelecontrôleur
contrôleurs'adresse
s'adresse
interprétation
interprétation float unX = [Link]() ; ààlalavue
vue pour lasaisie
pour la saisie
de
delalarequête
requête float unY = [Link]() ; des valeurs...
des valeurs...
saisirPoint()
saisirPoint()
...puis
...puislelecontrôleur
contrôleurs'adresse
s'adresse
[Link](unX, unY) ; au modèle
} au modèle
pour
pour l'affectationdes
l'affectation desvaleurs
valeurs
}
Point
+majPoint(a:float,o:float)
modèle +getAbscisse(): float
+getOrdonnee(): float
+distance(): float
+afficherDistance()
+afficherPoint()
vue +saisirAbscisse(): float
+saisirOrdonnee(): float
+saisirPoint()
contrôleur +gererSaisirPoint()
Point
+majPoint(a:float,o:float)
modèle +getAbscisse(): float
+getOrdonnee(): float
+distance(): float
+afficherDistance()
+afficherPoint()
vue +saisirAbscisse(): float
+saisirOrdonnee(): float
+saisirPoint()
contrôleur +gererSaisirPoint()
Les éléments d'une classe susceptibles de changer doivent être placés dans d'autres
classes liées à la première par composition
Point
+majPoint(a:float,o:float)
modèle +getAbscisse(): float
+getOrdonnee(): float
+distance(): float
+afficherDistance()
+afficherPoint()
vue +saisirAbscisse(): float
+saisirOrdonnee(): float
+saisirPoint()
contrôleur +gererSaisirPoint()
Point
+majPoint(a:float,o:float)
modèle +getAbscisse(): float
+getOrdonnee(): float
+distance(): float
+afficherDistance()
+afficherPoint()
vue +saisirAbscisse(): float
+saisirOrdonnee(): float
+saisirPoint()
contrôleur +gererSaisirPoint()
●
Manque d'indépendance
✔
Le modèle, la vue et le contrôleur risquent de dépendre structurellement
les uns des autres
✔
on ne peut plus confier le modèle, la vue et le contrôleur à des
concepteurs/développeurs distincts
●
Maintenance/extensibilité difficiles
modifier une des parties aura des conséquences sur les autres et sera difficile à organiser
●
Manque de souplesse
impossible de changer facilement la vue et/ou le contrôleur
[Link], dpt informatique, IUT Villetaneuse 18
Une meilleure conception
association bi-directionnelle
ModelePointPlan VuePointTextuel
+majPoint(a:float,b:float) ControleurConcretPoint +afficherDistance()
+getAbscisse(): float +setVue(uneVue:VuePoint) +afficherPoint()
+getOrdonnee(): float +gererSaisirPoint() +saisirAbscisse(): float
+distance(): float +saisirOrdonnee(): float
+saisirPoint()
private float x ;
private float y ;
public ModelePointPlan()
{ this.x = 0 ; this.y = 0 ;}
Utilisateur
"choix 1"
saisirPoint()
gererSaisirPoint()
abs
abs
saisirOrdonnee()
"ordonnée ?"
ord
ord
majPoint(abs, ord)
●
Mise à jour automatique des vues (design pattern observateur)
(les vues changent automatiquement quand le modèle change)
●
Mise à jour automatique des contrôleurs (design pattern observateur)
(les contrôleurs changent automatiquement quand le modèle change)
●
Séparation des vues et des contrôleurs (design pattern stratégie)
(on peut dynamiquement changer de contrôleur et/ou de vue)
●
Imbrication des vues (design pattern composite)
2) gère requête
Une
Unevue
vuepropose
propose: :
I)I)un
unensemble
ensemblede deservices
services(requêtes)
(requêtes)
ààl'utilisateur
l'utilisateur
II) 3.b) change d'affichage
II) un affichage desdonnées
un affichage des données(du(dumodèle)
modèle)
3.a) change d'état
1) choix requête
4.a) j'ai changé
quand dès
dèsque
quelelemodèle
modèlechange
changeilillelesignale
quandelle
elleen
enaabesoin
besoinde demettre
mettreààjour
joursasapartie
partieaffichage
affichage(II)
(II) aux
signale
lalavue interroge le modèle
vue interroge le modèle aux vues (4.a) et aux contrôleurs(4.b)
vues (4.a) et aux contrôleurs (4.b)
(par qui
quisesemettent
mettentààjour
jouren
enconséquence
(parexemple
exemplepour
pourafficher
affichercertaines
certainesdonnées
donnéesdu dumodèle)
modèle) conséquence
Les vues et les contrôleurs sont automatiquement avertis des changements du modèle
[Link], dpt informatique, IUT Villetaneuse 28
Mise à jour automatique des vues
(design pattern Observateur)
Les vues sont des observateurs du modèle (qui est l'observable)
1
<<interface>>
ModelePoint <<interface>>
Sujet
+majPoint(a:float,o:float) 1
+getAbscisse(): float +enregisterObservateur(o:Observateur)
+getOrdonnee(): float +supprimerObservateur(o:Observateur)
+distance(): float +notifierObservateurs()
1..*
<<interface>>
VuePoint
1..* +afficherDistance()
<<interface>>
<<interface>> +afficherPoint()
ModeleSujetPoint +saisirAbscisse(): float
Observateur
+saisirOrdonnee(): float
+actualiser() +saisirPoint()
On pourra référencer heritage multiple
un modele de point par entre interfaces
une des 3 interfaces suivantes
selon le contexte :
1) ModelePoint
2) Sujet
3) ModeleSujetPoint
ModelePointPlan
VuePointTextuel
+majPoint(a:float,b:float)
+afficherDistance()
+getAbscisse(): float
+afficherPoint() implémente la
+getOrdonnee(): float
+saisirAbscisse(): float méthode
+distance(): float implémente les
actualiser
+saisirOrdonnee(): float
+enregistrerObservateur(o:Observateur) méthodes d'un
Sujet (Observable) +saisirPoint()
+supprimerObservateur(o:Observateur)
+actualiser()
+notifierObservateurs()
1
<<interface>>
<<interface>>
ModelePoint
Sujet
+majPoint(a:float,o:float) 1
+getAbscisse(): float +enregisterObservateur(o:Observateur)
+getOrdonnee(): float +supprimerObservateur(o:Observateur)
+distance(): float +notifierObservateurs()
1..*
1..* <<interface>>
<<interface>> <<interface>> ControleurPoint
ModeleSujetPoint Observateur +setVue(uneVue:VuePoint)
+actualiser() +gererSaisirPoint()
implémente la
méthode
actualiser
ModelePointPlan
+majPoint(a:float,b:float) ControleurConcretPoint
+getAbscisse(): float +setVue(uneVue:VuePoint)
+getOrdonnee(): float +gererSaisirPoint()
+distance(): float implémente les
+actualiser()
méthodes d'un
+enregistrerObservateur(o:Observateur)
observable
+supprimerObservateur(o:Observateur)
+notifierObservateurs()
lelecontrôleur
contrôleurs'enregistre
s'enregistrecomme
comme
public void actualiser() Observateur du modèle
Observateur du modèle
{
...
}
instructions
instructionsexécutées
exécutéesquand
quandlelemodèle
modèledemande
demande
... au contrôleur de s'actualiser.
au contrôleur de s'actualiser.
}
[Link](v) ;
[Link]() ;
}
}
affichage
affichageinitiale
initialede
delalavue
vue
l'utilisateur
l'utilisateurentre
entrede
denouvelles
nouvelles
coordonnées
coordonnées
lalavue
vueest
estautomatiquement
automatiquementmise
mise
ààjour
jour
[Link], dpt informatique, IUT Villetaneuse 34
Dynamique d'une requête utilisateur
:VuePoint :ControleurPoint :ModelePoint
Utilisateur
"choix 1"
saisirPoint()
gererSaisirPoint()
abs
abs
ord
ord
actualiser()
actualiser()
afficherPoint()
<<interface>>
VuePoint
<<interface>>
+afficherDistance()
ControleurPoint 1 1..*
+afficherPoint()
+setVue(uneVue:VuePoint) +saisirAbscisse(): float
+gererSaisirPoint() +saisirOrdonnee(): float
+saisirPoint()
+setControleur(nouveauControleur:ControleurPoint)
ControleurPointGraphique VuePointGraphique
+setVue(uneVue:VuePoint) +afficherDistance()
+gererSaisirPoint() +afficherPoint()
+saisirAbscisse(): float
+saisirOrdonnee(): float
+saisirPoint()
+setControleur(nouveauControleur:ControleurPoint)
[Link](v) ; on
[Link]() ; onsupprime
supprimel'association
l'association
entre
entre le modèle et le contrôleurcourant
le modèle et le contrôleur courant
[Link](c1) ;
On
Onassocie
associelalavue
vuevvau
aunouveau
nouveaucontrôleur.
contrô[Link]
vuevvsera
serainterprétée
interprétéedifféremment
différemment
(pratique courante pour utiliser une vue avec une autre application,
(pratique courante pour utiliser une vue avec une autre application,
ou
ouune
uneautre
autreversion
versiond'une
d'uneapplication)
application)
VueSimple VueComposite
+fonctionVue() +ajouterComposant() 0..1
+supprimerComposant()
+getComposant()
+fonctionVue()
1..*
<<interface>>
IObservateur Vue
+actualiser() +actualiser()
+fonctionVue()
Controleur
+gererFonctionVue()
Modele +actualiser()
+fonctionModele()
+enregisterObservateur(o:Observateur)
+supprimerObservateur(o:Observateur)
+notifierObservateurs()
1..*
<<interface>>
<<interface>> IVue
1..* IControleur 1 1..*
+fonctionVue()
+gererFonctionVue()