Architecture
MVC – Design Pattern
Modèle+Vue : observateur – Vue : composite – Contrôleur+Vue : stratégie
SOMMAIRE
SOMMAIRE 1
MVC - PATTERN COMPOSE 2
Architecture - Rappels 2
Principe de base : séparer l’interface utilisateur et les traitements 2
Architecture client-serveur 2
Architecture 3 tiers 3
Architecture N tiers 4
MVC 5
Le MVC 5
Détails des design patterns 7
Le pattern Observer (délégation) 7
Le pattern Composite 9
Le pattern Strategie 11
Exemples 13
Diagramme de classe 13
Edition juin 2018
INSIA – Design Patterns en JAVA – MVC- page 2/15 - Bertrand LIAUDET
MVC - PATTERN COMPOSE
Architecture - Rappels
Principe de base : séparer l’interface utilisateur et les traitements
L’architecture de base consiste à séparer l’interface utilisateur et les traitements :
• Lire
• Traiter
• Afficher
Lire et Afficher correspondent à l’IHM. On a donc une simple distinction entre :
• IHM
• Traitements
Architecture client-serveur
L’architecture client-serveur consiste à gérer à part les données avec un serveur de BD.
Le serveur de BD historique, c’est ORACLE.
Architecture 3 tiers
L’architecture 3 tiers est la base des architectures et fait la synthèse entre la classique distinction entre l’IHM et les traitements et l’architecture client-serveur.
L’architecture 3 tiers consiste à appliquer les principes suivants :
• La présentation (l’IHM), est prise en charge par le poste client. C’est le client léger : le navigateur.
• Les données sont gérées de façon centralisée : c’est le serveur de base de données.
• La logique applicative (les traitements) est prise en charge par un serveur intermédiaire.
A noter qu’on distingue entre des traitements locaux visant essentiellement le contrôle et l’aide à la saisie et les traitements globaux qui constituent l’application elle-même.
Les traitements locaux sont pris en charge par le poste client.
SERVICES RENDUS MACHINES INTERFACES
IHM Navigateur HTML
Interfaces de
technologies internet standards
TRAITEMENTS Locaux
Globaux Serveur Web.
Services HTTP.
Services applicatifs Interfaces client- serveur spécifiques
DONNEES Serveur de données
INSIA – Design Patterns en JAVA – MVC- page 4/15 - Bertrand LIAUDET
Architecture N tiers
L’architecture N tiers conserve les 3 niveaux de l’architecture 3 tiers. Toutefois, elle consiste à distribuer plus librement la logique applicative de qui facile la répartition de la charge et la maintenabilité des différentes parties.
Architecture 4 tiers – MMVC
L’architecture 4 tiers ajoute une couche « manager » à la gestion de donnée, ce qui permet d’avoir une couche de classe-métiers indépendante de la couche d’accès à la BD : les managers.
MVC
Le MVC
L’objectif du MVC est de séparer les objets de l’interface utilisateur des objets métier pour faciliter la maintenance.
Le modèle
C’est le module de calcul, le module métier. Il s’occupe de la représentation des données, des traitements effectués sur ces données et de leur gestion.
La vue : pattern composite
Elle gère la saisie et l’affichage. La vue étant du HTML, les balises ont une structure d’arbre. L’inclusion dans la page peut être gérée comme un arbre : le pattern composite permet cela.
Le contrôleur
Permet de créer une couche entre l’interface utilisateur (la vue) et le modèle : cette couche contient les appels des méthodes du modèle.
INSIA – Design Patterns en JAVA – MVC- page 6/15 - Bertrand LIAUDET
Vue + Modèle : pattern Observateur
La vue et le modèle mettent en œuvre le pattern Observateur.
La vue est l’observateur du modèle. Le modèle l’observable.
Quand une information du modèle est modifiée, l’observateur (la vue) est automatiquement mis à jour.
Vue + contrôleur : pattern Stratégie
La vue et le contrôleur compose l’interface utilisateur.
La vue fait appel aux méthodes de son contrôleur à travers une interface en mettant en œuvre le pattern Strategie.
Ainsi :
• On peut changer de contrôleur et garder la même interface utilisateur (c’est l’exemple du TempoDJ et TempoCoeur de DP TLP).
• On peut changer d’interface utilisateur et garder le même contrôleur.
Présentation détaillée CF. DP TLP
Java ESIEE Morelle
Détails des design patterns
Le pattern Observer (délégation)
http://rpouiller.developpez.com/tutoriel/java/design-patterns-gang-of-four/?page=page_4#LVI- G
Description du pattern (objectif, définition)
• Un objet (le sujet) est observé par plusieurs autres (les observateurs). Quand un événement arrive à l’objet observé, on prévient tous ceux qui l’observent (notification).
• Le pattern construit donc une dépendance entre un sujet et des observateurs de sorte que chaque modification du sujet soit notifiée aux observateurs afin qu’ils puissent mettre à jour leur état.
UML
sujet
setEtat : ...
notifie() notifie () :
Pour chaque o de observeurs : o.actualiser
actualise : etatObservé = sujet.getEtat ()
<<use>>
* observateurs
<<implemente>> <<implémente>>
<<interface>>
Sujet
+ + +
ajoute ( observateur) retire ( observateur) notifie ()
ObservateurConcret - etatObservé Client
+ main (String args[]) : void
SujetConcret - etat
+ +
setEtat () getEtat ()
<<interface>>
Observateur
+ actualise ()
Description de la structure Ø Coté Sujet
Le sujet observé implémente l’interface « Sujet » : ça l’oblige à se doter de méthodes pour gérer les « Observateurs ». Le sujet gère donc une collection d’Observateurs : on peut ajouter ou retirer un observateur de la collection. Toute classe implémentant l’interface Observateur pourra donc faire partie de la collection.
INSIA – Design Patterns en JAVA – MVC- page 8/15 - Bertrand LIAUDET
Le sujet implémente une méthode standard : « notifie » qui consiste à actualiser tous les observateurs. La méthode notifie appelle la méthode actualise des observateurs. Actualise() concret est obtenu par l’observateur concret (polymorphisme, logique de pattern Strategie).
La méthode « notifie » est appelée par le sujet à chaque fois qu’il modifie son état (qu’il sette son état).
Ø Coté Observateur
L’observateur implémente une méthode « actualise ».
La méthode actualise met à jour l’observateur en récupérant l’état du sujet : en effet, l’observateur contient un attribut sujet concret.
Que l’observateur contienne un attribut qui implémente l’interface « Sujet » lui permet aussi de pouvoir s’enregistrer comme observateur auprès du sujet et aussi de se retirer.
Ø Remarque
Une association orientée entre deux interfaces veut dire qu’on a en réalité une association orientée entre une classe implémentant l’interface de départ et l’interface d’arrivée.
Séquence de la mise à jour
1. Le client setEtat() le sujet
2. Le setEtat() du sujet notifie() le sujet
3. Le notifie() du sujet actualise() tous les observateurs
4. L’actualise() de l’observateur récupère l’état du sujet, soit par les paramètres d’appel de l’actualise, soit par un getEtat() du sujet
Le pattern Composite
http://rpouiller.developpez.com/tutoriel/java/design-patterns-gang-of-four/?page=page_3#LV-C Objectif du pattern
Gérer une structure d’arbre Principe de réalisation
Un arbre est constitué de nœuds. Un nœud peut être une feuille (n’avoir aucun enfant) ou se ramifier en plusieurs nœuds.
Diagramme de classes
L’agrégation de Nœud vers ElementArbre est bi-directionelle : ElementArbre contient un attribut
« parent » qui est un Nœud. On peut ajouter une méthode getParent qui retourne un Nœud dans la classe ElementArbre.
getEnfants() : return enfants;
getEnfants() : return null;
<<use>>
* - enfants
parcourirTousLesElementArbre : traitements();
for(ElementArbre e : enfants) e.parcourirTousLesElementArbre();
parcourirTousLesElementArbre : traitements();
Main
+ main (String args[]) : void
ElementArbre
# nom : String +
+ + + +
<<Constructor>>
<<abstract>>
<<abstract>>
<<abstract>>
<<abstract>>
ElementArbre (final String nom) parcourirTousLesElementArbre () ajouterEnfant (final ElementArbre e) retirerEnfant (final ElementArbre e) getEnfants ()
: void : void : void
: List<ElementArbre>
Feuille
+ + + + +
<<Constructor>> Feuille (final String nom) parcourirTousLesElementArbre () ajouterEnfant (final ElementArbre e) retirerEnfant (final ElementArbre e) getEnfants ()
: void : void : void
: List<ElementArbre>
Noeud
+ + + + +
<<Constructor>> Noeud (final String nom) parcourirTousLesElementArbre () ajouterEnfant (final ElementArbre e) retirerEnfant (final ElementArbre e) getEnfants ()
: void : void : void
: List<ElementArbre>
INSIA – Design Patterns en JAVA – MVC- page 10/15 - Bertrand LIAUDET
Explications
• La méthode « parcourirTousLesElements » est la méthode qui permet à partir de la racine de l’arbre d’accéder à tous les éléments de l’arbre en faisant n’importe quel traitement (un affichage par exemple). L’implantation de la méthode dans un nœud est récursive : elle fait appel à cette même méthode pour tous les enfants du nœud en question. La condition de sortie de la récursivité se fait quand on arrive sur un feuille : dans ce cas, la méthode se contente de faire le traitement sans appel récursif.
• Ce pattern est donc fondamentalement algorithmique : il permet l’implantation d’un algorithme de parcours d’arbre.
• A noter qu’on a choisi de mettre les méthodes de gestion des enfants en méthode abstraites : ces méthodes sont définies dans la classe « Nœud » et ne font rien dans la classe « Feuille ».
Ce choix permet de gérer abstraitement des ElementArbre dans le main, sans se soucier de savoir si ce sont des feuilles ou des nœuds. On pourrait aussi choisir de gérer ces méthodes uniquement dans la classe Nœud.
Le pattern Strategie
http://rpouiller.developpez.com/tutoriel/java/design-patterns-gang-of-four/?page=page_4#LVI-I Description du pattern (objectif, définition)
• Encapsule des comportements d’une même famille (des méthodes) et utilise la délégation pour savoir lequel utiliser.
• « sette » des méthodes à travers une interface : permet ainsi d’avoir une méthode
« variable ».
• Adapter le comportement d’un objet en fonction d’un besoin sans changer les interactions, et donc indépendamment du client.
• Définir une famille d'algorithmes interchangeables et permettre de les changer indépendamment de la partie cliente.
Principes de résolution
Quand un objet Entité est instancié par un objet Client, il est instancié avec une stratégie concrète (un objet de Strategie1 ou un objet de Strategie2). De ce fait, la méthode calcul de l’objet Entité (qui exécute strategie.calcul() ) réagit différemment selon la stratégie concrète instancié.
Ainsi, les objets de la classe Entité accèdent de façon polymorphe aux méthodes de la classe
« Stratégie »
La classe Stratégie est une interface qui définit les comportements.
Les stratégies concrètes réalisent cette interface.
INSIA – Design Patterns en JAVA – MVC- page 12/15 - Bertrand LIAUDET
UML
1
# strategie Entité
+ calcul ()
Strategie 1 + <<Implement>> calcul () Strategie
+ calcul () Client
+ main (String args[]) : void
Strategie 2 + <<Implement>> calcul ()
Le calcul() Entité exécute strategie.calcul().
En fonction de l’objet stratégie instancié dans l’objet entité, un calcul s’exécute ou un autre.
Appliqué au MVC
La vue fait appel aux méthodes de son contrôleur à travers une interface en mettant en œuvre le pattern Strategie.
L’objet vue contient une interface contrôleur instanciée avec un contrôleur concret.
Ainsi :
• On peut changer de contrôleur et garder la même interface utilisateur. Le nouveau contrôleur devra réaliser l’interface contrôleur (c’est l’exemple du TempoDJ et TempoCoeur de DP TLP dans l’exemple ci-dessous).
• On peut changer d’interface utilisateur et garder le même contrôleur. La nouvelle interface utilisateur devra utiliser les méthodes de l’interface contrôleur.
Exemples
Diagramme de classe Modèle Tempo – DP TLP
progression modele
vue modele
controleur
barre
<<use>>
<<use>>
* observateursBPM InterfaceModeleTempo
+ + + + + + + + +
initialiser () marche () arret () setBPM (..) getBPM () registerObserver (..) removeObserver (..) registerObserver (..) removeObserver (..)
: void : void : void : void : int : void : void : void : void
BarrePulsante
JProgressBar Runnable
InterfaceControleur
+ + + + +
start () stop ()
augmenterBPM () diminuerBPM () setBPM (..)
: void : void : void : void : void
ControleurTempo
ModeleTempo
MetaEventListener
ObservateurBPM + majBPM () : void TestDJ
VueDJ
ActionListener
Ici, l’interface contrôleur est la stratégie de la vue : pattern stratégie.
La vue est l’observateur du modèle : pattern observateur.
La vue n’est pas organisée avec un pattern composite.
INSIA – Design Patterns en JAVA – MVC- page 14/15 - Bertrand LIAUDET
Diagramme de séquence
start( )
augmenterBPM( ) L'utilisateur choisit le sous menu Commandes/Demarrer de la VueDJ
Ca lance la méthode "start" 'demarrer" du controleur
L'utilisateur choisit d 'incrémenter le BPM de la VueDJ Ca lance la méthode "augmenterBPM" du controleur new
new ( modele )
new ( modele )
registerObserver(ObservateurBPM)
creerVue( ) initialiser( )
-
-
pseudo appel à Commande / Demarrer
marche( )
desactiverChoixStart( ) activerChoixStop( )
- -
pseudo appel à l'incrémentation du BPM
getBPM( ) nb BPM setBPM(nb BPM + 1)
notifierObservateursBPM( )
-
- Acteur_1
new ( modele ):ModeleTempo
controleur:ControleurTempo
vue:VueDJ
- - majBPM( )
getBPM( ) start( )
augmenterBPM( ) new
new ( modele )
new ( modele )
registerObserver(ObservateurBPM)
creerVue( ) initialiser( )
-
-
pseudo appel à Commande / Demarrer
marche( )
desactiverChoixStart( ) activerChoixStop( )
- -
pseudo appel à l'incrémentation du BPM
getBPM( ) nb BPM setBPM(nb BPM + 1)
notifierObservateursBPM( )
-
- -
- majBPM( )
getBPM( )
Modèle Tempo + Cœur – DP TLP
coeur
progression modele
vue modele
vue
modele
controleur
barre
* observateursBPM
<<use>>
<<use>>
<<use>>
<<use>>
*
observateursBattements AdaptateurCoeur
InterfaceModeleTempo
+ + + + + + + + +
initialiser () marche () arret () setBPM (..) getBPM () registerObserver (..) removeObserver (..) registerObserver (..) removeObserver (..)
: void : void : void : void : int : void : void : void : void
BarrePulsante
JProgressBar Runnable
ControleurCoeur
InterfaceControleur
+ + + + +
start () stop ()
augmenterBPM () diminuerBPM () setBPM (..)
: void : void : void : void : void
ControleurTempo InterfaceModeleCoeur
+ + + + +
getRythmeCardiaque () registerObserver (..) removeObserver (..) registerObserver (..) removeObserver (..)
: int : void : void : void : void
ModeleCoeur
ModeleTempo MetaEventListener
ObservateurBPM + majBPM () : void
ObservateurBattements + majTempo () : void TestCoeur
TestDJ
VueDJ
ActionListener
Ici on voit mieux le pattern Stratégie : le contrôleur est la stratégie de la vue.