Plan
Les patrons de conception
(Design patterns)
Riadh BEN HALIMA
Wajdi LOUATI
[Link]@[Link]
[Link]@[Link]
Historique
Motivation
Notion de patron dabord apparue en architecture :
Chaque modle [patron] dcrit un problme qui se manifeste constamment
dans notre environnement, et donc dcrit le cur de la solution de ce problme,
dune faon telle que lon peut rutiliser cette solution des millions de fois. [Livre:
The Timeless Way of Building, Oxford University Press 1979]
Projeter la notion de patron du logiciel : "design pattern"
premiers patrons partir de 1987 (partie de la thse de Erich Gamma)
puis Richard Helm, John Vlissides et Ralph Johnson (Gang of Four, GoF)
premier catalogue en 1993 : Elements of Reusable Object-Oriented Software
Larchitecte Christopher Alexander le dfinit comme suit:
Pourquoi dfinir des patrons de conception
larchitecture des btiments
la conception des villes et de leur environnement
Historique & Motivation
Le patron Strategy
Le patron Observer
Le patron Decorator
Le patron Abstract Factory
Le patron Singleton
Le patron Command
Le patron Adapter
Le patron Faade
Complmentaire avec les API
modles de conception= patrons de conception= motifs de conception= design
patterns
3
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Une API propose des solutions directement utilisables
Un patron explique comment structurer son application avec une API
Patron de conception dans le cycle de dveloppement
Vocabulaire:
Construire des systmes plus extensibles, plus robustes au changement
Capitaliser lexprience collective des informaticiens
Rutiliser les solutions qui ont fait leur preuve
Identifier les avantages/inconvnients/limites de ces solutions
Savoir quand les appliquer
Intervient en conception dtaille
Reste indpendant du langage dimplantation
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Intrt et utilisation des patrons de
conception
Dfinition
Dfinition : "Un patron de conception (design pattern)
La meilleure manire dutilisation des patrons de conception est de les mmoriser
en tte, puis reconnaitre leurs emplacements et les appliquer dans la conception
des applications
dcrit une structure commune et rptitive de
composants en interaction (la solution) qui rsout un
problme de conception dans un contexte particulier
Les concepts de lorient objet tels que
labstraction, lhritage, et le polymorphisme ne
te rendent pas un bon concepteur!
Un concepteur pense crer une conception
flexible qui est maintenable et fait face aux
changements
Au lieu de la rutilisation de code, on parle de la
rutilisation de lexprience avec les patrons
Un bon patron de conception :
rsout un problme
correspond une solution prouve
favorise la rutilisabilit, lextensibilit, etc.
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Ce quil ne faut pas attendre des patrons
de conception
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Trois sortes de patrons
Une solution universelle prte lemploi
Une bibliothque de classes rutilisables
Lautomatisation totale de linstanciation dun
patron de conception
La disparition du facteur humain
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
SimUDuck:
Conception (1/22)
Le patron
"Strategy"
Objectif: dveloppement dun jeu de simulation dun bassin
pour les canards
Besoin: nager, cancaner, afficher, etc..
Supporter une large varit de canards
Conception: OO
Une supre classe Canard (Duck) dont tous les canards hritent
Duck
quack()
swim()
display()
Abstract
Autres types de Ducks
Objectif: Innovation (pour impressionner et vendre +)
Besoin: simuler le vol des canards!
Conception: OO
Ajouter la mthode fly() la supre classe
RedHeadDuck
display()
display()
10
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
SimUDuck : Innovation (2/22)
MallardDuck
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
SimUDuck :
Problmes (3/22)
Besoin: Au moment de la dmonstration du simulateur, on nous
demande de simuler des canards en caoutchouc
Conception: OO
Ajouter la classe RubberDuck qui hrite de la supre classe Duck
Duck
quack()
swim()
Modification apporte
Duck
quack()
swim()
fly()
Hriter par tous les canards
display()
Le caoutchouc ne vole pas
fly()
display()
Autres types de Ducks
11
MallardDuck
RedHeadDuck
MallardDuck
RedHeadDuck
display()
display()
display()
display()
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
12
? Le caoutchouc ne cancane pas
RubberDuck
display()
quack(){
Redfinir squeak
}
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
SimUDuck :
Constat (4/22)
SimUDuck :
Solution?? (5/22)
Problme 1: Le canard en caoutchouc ne cancane pas!
Solution : Redfinir la mthode quack() squeak()
(rsolu)
Problme 2: Le canard en caoutchouc ne vole pas!
Toutefois, il hrite la mthode fly() de la supre classe
Duck!
Constat:
13
Nouveau type de canard: Canard en bois
Problmes levs:
Ce canard ne cancane pas
Ce canard ne vole pas
Solution: Redfinir la mthode fly() de RubberDuck
RubberDuck
display()
quack(){ squeak }
fly(){
Redfinir rien
}
Solution: redfinir (une autre fois) les mthodes quack() et fly()
Hypothse: On nous demande de mettre jour SimUDuck tous les 6 mois: La
spcification demeure changeante
Vrifier fly() et quack() pour chaque nouveau canard
R-crire (si besoin) fly() et quack()
Solution possible pour contourner le problme: les interfaces
Interface
Flyable
fly()
Inconvnients de lutilisation de lhritage
15
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
SimUDuck :
Des interfaces? (7/X)
WoodenDuck
display()
quack(){
Redfinir rien
}
fly(){
Redfinir rien
}
Question: est ce que cest rsolu pour tous types de canards?
14
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
SimUDuck :
Un autre canard (6/22)
Problme 2: Le canard en caoutchouc ne vole pas! Toutefois, il
hrite la mthode fly() de la supre classe Duck!
Ce que nous avons cru une utilisation formidable de lhritage
dans le but de la rutilisation, sest termin mal au moment de
la mise jour!
Une mise jour du code a caus un effet global sur
lapplication!
Il est difficile de connaitre le comportement de tous les canards
Un changement non-intentionnelle, affecte les autres canards
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
16
Duck
Quackable
quack()
swim()
display()
MallardDuck
RedHeadDuck
RubberDuck
WoodenDuck
display()
fly()
quack()
display()
fly()
quack()
display()
quack()
display()
Que dites vous de cette
conception ?
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
SimUDuck :
Inconvnients (8/22)
SimUDuck :
Moment de rflexion (9/22)
Duck
Flyable
fly()
Quackable
swim()
display()
quack()
Pas toutes les sous-classes qui ont besoin de voler (fly)
ou de cancaner (quack)
RedHeadDuck
RubberDuck
WoodenDuck
display()
fly()
quack()
display()
fly()
quack()
display()
quack()
display()
Duplication de code: mthodes fly() et quack() dans les sous-classes
Autant dinterfaces tant quil y a un ensemble de canards ayant exclusivement un
comportement commun (pondre: lay() pour les canards qui peuvent dposer un uf)
Les interfaces Flyable et Quackable rsolvent une
partie du problme
Constat:
MallardDuck
Lhritage nest pas la bonne solution
Dtruit compltement la rutilisation du code pour ces
comportements
La maintenance et la mise jour reprsentent un vrai calvaire
Supposant quil existe plus quune faon de voler
Maintenance plus difficile
Problme: si on veut modifier/adapter lgrement la mthode fly(), il faut le faire
pour toutes les classes des canards (10 classes, 100, ou +)
17
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
SimUDuck :
Solution (10/22)
18
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
SimUDuck :
Principe de conception (11/22)
Solution:
Design pattern : solution ultime, cheval blanc, sauveur
Rgle
1: Identifier les aspects variables de mon
application et les sparer de ce qui reste invariant
Trouvons une solution avec l"ancienne-mode" et ce en
applicant les bonnes principes de la conception OO
Concevoir une application, ou un besoin de
modification/changement peut tre appliqu avec le
moindre possible dimpact sur le code existant
Cest
la base de tous les patrons de conception
Systme plus flexible+peu de consquences inattendues
Mise
Prendre
la partie qui varie et lencapsuler. De cette
faon, un changement ultrieur affecte la partie
variable, sans toucher celle invariable
Donner des raisons de changement de code
dans votre application
19
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
en uvre
20
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
SimUDuck :
Sparation (12/22)
SimUDuck :
Conception des comportements (13/22)
La classe Duck est toujours la supre classe
Les comportements fly() et quack() sont retirs, et mis dans une
autre structure
Comportements
Mettre dehors ce qui varie
Duck class
Le comportement Fly
Le comportement Quack
Conception initiale: linflexibilit des comportements a engendr
des troubles
On veut affecter les comportements aux instances des Ducks
tout en permettant:
La cration dune instance (MallardDuck),
Linitialisation avec un type de comportement (type de vol)
La possibilit de changer le type de vol dynamiquement (?)
Rgle 2: Programmer des interfaces, et non des
implmentations
Invariable
Variable
21
22
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
SimUDuck :
Conception des comportements (14/22)
FlyBehavior
QuackBehavior
fly()
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
SimUDuck :
Intgration des comportements(15/22)
quack()
Programmer pour les super-types!
On utilise des interfaces pour reprsenter chaque
comportement: FlyBehavior et QuackBehavior
La supre classe Duck, dont hrite tous les canards
Duck
FlyWithWings
fly() {
//vol
}
FlyNoWay
fly() {
//rien-ne vol pas
}
Quack
quack(){
//quack
}
Squeak
quack(){
//squeak
//rubber
}
MuteQuack
quack(){
//rien-ne
//cancane pas
}
Consquences:
23
On peut ajouter un nouveau comportement sans modifier ni le code des
comportements existants, ni le code des classes des canards qui utilisent les
comportements voler/cancaner
Avec cette conception, dautres objets peuvent rutiliser le comportement fly et
quack, parce quils ne sont plus cachs dans les classes canards.
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
FlyBehavior fbehavior;
QuackBehavior qbehavior;
Variable dinstance
du type INTERFACE
performQuack()
swim()
display()
performFly()
//.
Ces mthodes remplacent quack() et fly()
La cl: le canard dlgue les comportements fly et quack,
au lieu dutiliser les mthodes fly() et quack() dfinies
dans la supre classe Duck.
24
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
SimUDuck :
Implmentation de la supre classe(16/22)
SimUDuck :
Implmentation dun canard (17/22)
La supre classe Duck, dont hrite tous les canards
public class Duck{
QuackBehavior qbehavior;
FlyBehavior fbehavior;
//
Cette classe inclut les mthodes ralisant
le comportement fly et quack, par hritage
(performQuack(), etc..)
Chaque type de canard initialise ces attributs
selon ses besoins.
(par FlyWithWings pour le MallardDuck )
public void performQuack(){
[Link]();
}
//..
}
Grace au polymorphisme, la bonne mthode sera
invoque dans la sous-classe du type de canard.
(Dlgue la classe grant le comportement)
25
public class MallardDuck extend Duck{
public MallardDuck (){
Initialisation des attributs dclars
fbehavior = new FlyWithWings();
dans la supre classe Duck
qbehavior = new Quack();
}
public void display(){
[Link]("Je suis un canard Mallard");
}
}
26
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
SimUDuck :
Tester le code du canard(18/22)
Dvelopper et compiler [Utiliser NetBeans/Eclipse]:
SimUDuck :
Le comportement dynamique (19/22)
La classe abstraite Duck ([Link])
Le comportements: [Link], [Link] et
Le comportement : [Link], [Link], [Link] et
[Link]
Les classes [Link] et [Link]
Tester toutes les mthodes des canards crs dans un main:
[Link]
27
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Changement dynamique de comportement
[Link],
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Ajouter les mthodes: setFlyBehavior() et setQuackBehavior()
Dvelopper le canard RedHeadDuck ([Link])
Implanter le nouveau comportement "vole-force-fuse"
FlyRocketPowered ([Link])
Tester le nouveau canard dans un main [Link]
Changer le comportement "voler" de FlyWithWings
FlyRocketPowered. Penser utiliser le setter afin dobtenir ces
deux affichages: "Je peux voler" & "Je vole comme une fuse"
Donner (et ne pas implmenter) les modifications faire afin
dajouter le comportement manger: eat()
28
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
SimUDuck :
La conception finale (20/22)
performQuack()
swim()
display()
performFly()
setFlyBehavior()
setQuackBehavior()
\\autre mthodes
Chaque canard possde un FlyBehavior et QuackBehavior qui
dlgue flying et quacking
Composition (mettre les 2 classes ensemble)
Encapsuler une famille dalgorithmes dans leur propre ensemble
de classes
Remplacer lhritage pour favoriser le changement dynamique du
comportement
implements
Quack
quack(){
//quack
}
Squeak
quack(){
//squeak
//rubber
}
MuteQuack
quack(){
//rien-ne
//cancane pas
}
FlyBehavior
fly()
extends
WoodenDuck
display(){
\\canard en bois
}
Algorithmes
interchangeables
FlyWithWings
fly() {
//vole
}
Rgle 3: Favoriser la composition sur lhritage
implements
FlyNoWay
fly() {
//ne vole pas
}
30
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
SimUDuck :
Notre premier patron (22/22)
Has-a: liaison intressante
QuackBehavior qbehavior;
FlyBehavior fbehavior;
29
QuackBehavior
quack()
Duck
MallardDuck
display(){
\\canard Mallard
}
SimUDuck :
Composition/Hritage (21/22)
Notre premier patron: STRATEGIE
Le patron stratgie cherche principalement sparer
un objet de ses comportements/algorithmes en
encapsulant ces derniers dans des classes part.
Les avantages du patron
Si les algorithmes/comportements sont dans une classe a part,
il est beaucoup plus facile de:
Pour ce faire, on doit alors dfinir une famille de
comportements ou dalgorithmes encapsuls et
interchangeables.
31
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
32
se retrouver dans le code principale
enlever, ajouter et modifier un algorithme/comportement
diminuer lutilisation de tests conditionnels
liminer la redondance et le couper/coller
accrotre la rutilisabilit du code ainsi que sa flexibilit
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Limplmentation du patron
Pour implmenter le patron Strategy on doit:
1. Dfinir une interface commune tout les algorithmes ou
comportements de mme famille.
Ceci ce fait habituellement en crant une classe abstraite.
2. Crer les classes comportant les algorithmes ou les
comportements partir de linterface commune.
3. Utiliser la stratgie voulue dans le code de lobjet.
33
Abstraction, Encapsulation, Polymorphisme & Hritage
Principes de lOO
35
Encapsuler ce qui varie
Favoriser la composition sur lhritage
Programmer avec des interfaces et non des implmentations
Patron de lOO (stratgie)
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Rcapitulatif (2/2)
Bases de lOO:
34
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Rcapitulatif (1/2)
Reprsentation du patron
Le patron stratgie dfinit une famille dalgorithmes, les
encapsule, et les rend interchangeable. Ce patron laisse
lalgorithme varier indpendamment du client quil lutilise.
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Connaitre les bases de lOO ne fait pas de toi un bon concepteur
Les meilleurs conception OO sont rutilisable, flexible et
maintenable
Les patrons nous guident construire des systmes avec les bonnes
qualits de la conception OO
Les patrons sont des expriences prouves dans lOO
Les patrons ne donnent pas de code, mais plutt des solutions
gnrales pour des problmes de conception
Les patrons de sont pas invents, mais dcouverts
La majorit des patrons et des principes adresses les problmes de
changement dans le logiciel
On essaie toujours de prendre ce qui varie des systmes et on
lencapsule
Les patrons offrent un langage partag qui peut maximiser la valeur
de la communication avec les autres dveloppeurs
36
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Exercice (1/2)
Exercice (2/2)
Ci-dessous, on donne lensemble de classes et interfaces dun jeu
daction et daventure. Il y a des classes dindividus avec des
classes pour les comportements darmes que les individus
peuvent utiliser. Chaque individu peut utiliser une seule arme la
fois, mais peut la changer tout moment durant le jeu. La tche
demande est dordonner le tout.
Individu
ComportementArme arme;
combattre()
Display ()
Reine
Display(){.}
UtiliseArme(){\\abattre avec
couteau }
Display(){.}
setArme(ComportementArme ca) {
[Link]=ca;
}
37
2.
3.
1.
2.
3.
Chevalier
ComportementCouteau
Archer
Arranger les classes
Identifier les classes, les classes abstraites des interfaces
Relier les entits pas des flches ou:
1.
Display(){.}
ComportementArc&Fleche
UtiliseArme(){\\abattre avec
arc et flche}
Mettre la mthode setArme() dans la classe
correspondante
Implmenter et tester cette conception dans un main.
Penser changer dynamiquement le comportement de
larcher aprs avoir finir ces arcs.
4.
5.
ComportementArme
UtiliseArme();
reprsente extends
reprsente implements
reprsente has-a
ComportementEpee
UtiliseArme(){\\abattre avec
pe}
38
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Station mto:
Spcification (1/14)
Le patron
"Observer"
Objectif: Construire une nouvelles gnration de stations
dobservation mto sur Internet
Besoin: Afficher les conditions courantes, les statistiques
mtorologique et les prvisions mto.
Conception: OO
39
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Poursuivre les conditions mtorologiques (Temprature,
Humidit, Pression, etc.)
On veut mettre en uvre une API (ENIS-METEO) de faon
que dautres dveloppeurs peuvent crire leur propre afficheur
de mto.
40
Une classe WeatherData qui rcupre les donnes de la station
mto (ENIS-METEO) et les offre aux afficheurs.
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Station mto:
Conception (3/14)
Station mto:
Analyse (2/14)
WeatherData
Afficher
Capteur
dhumidit
Capteur de
temprature
Weather Station
WeatherData
Object
Le fournisseur ENIS-METEO
Conditions
courantes
41
Nous allons dvelopper trois afficheurs:
A implmenter
Il faut crer une application qui utilise lobjet WeatherData afin de
mettre jour trois afficheurs: les conditions courantes, les statistiques
mtorologiques & les prvisions mto.
conditions courantes ([Link])
statistiques mtorologique ([Link])
prvisions mto ([Link])
Rq: On ne sintresse pas la manire dont les variables sont fixes.
On suppose que lobjet WeatherData connait comment les mettre
jour partie de la station ENIS-METEO
42
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Station mto:
Une solution possible (4/14)
Station mto:
Constat (5/14)
public class WeatherData
{
//attributs
Rcuprer les mesures les
plus rcentes
Problme : En codant des implmentations concrtes, on ne peut pas
ajouter/supprimer dautres afficheurs, sans faire un changement du
programme!
void setMeasurement(){
float temperature = getTemperature();
float humidity = getHumidity()
float pressure = getPressure()
1.
statisticsDisplay. update(temperature, humidity, pressure);
2.
forecastDisplay. update(temperature, humidity, pressure);
}
3.
//autres mthodes
Mettre jour les afficheurs
avec les nouvelles mesures
43
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Rq: on peut au moins utiliser une interface qui contient la
mthode update().
Solution : le patron observer
Exemple:
currentConditionsDisplay. update(temperature, humidity, pressure);
Cette mthode sera appele chaque
fois quon met jour les mesures
measurementChanged()
\\autre mthodes
Capteur de
pression
getTemperature()
getHumidity()
getPressure()
Tirer (pull)
Ces trois mthodes retournent les
mesures les plus rcentes
4.
44
Une maison ddition commence ldition dun journal
Vous vous inscrivez ce journal, et pour chaque nouvelle
dition, vous recevez votre copie
Vous vous dsinscrivez lorsque vous ne voulez plus recevoir
des journaux
Les gens, les htels etc. peuvent constamment sinscrire et se
dsinscrire ce journal.
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Station mto:
Publier/Souscrire= Patron Observer (6/14)
Lorsque les donnes du sujet changent,
les observateurs sont notifis
Station mto:
Patron Observer : Sinscrire (7/14)
Les observers sont
inscrits au Sujet afin de
recevoir les mise jour
Lobjet Sujet gre des
octets de donnes
2
2
Les objets Observers
Les objets Observers
45
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Station mto:
Patron Observer : Notification(8/14)
46
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Station mto:
Patron Observer : Dsinscrire (9/14)
Maintenant, le Mouse est un
observer, il reoit les
notifications du Sujet
8
8
8
Nouvel entier
Les objets Observers
47
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Les objets Observers
48
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Station mto:
Patron Observer : Notification (10/14)
Maintenant, le Dog nest plus un
observer, il ne reoit plus les
notifications du Sujet
Station mto:
Le patron Observer (11/14)
Dfinition:
Observer
12
Le patron observer dfinit une dpendance 1--plusieurs
entre des objets de faon que chaque changement de
ltat de lobjet, tous ces dpendants sont notifis et mis
jour automatiquement.
12
Les objets dpendants
1--plusieurs
8
8
8
Nouvel entier
Les objets Observers
Lobjet qui tient les mises
Mise jour/notification
jours
automatique
49
Station mto:
Diagramme de classes du patron (12/14)
Chaque Subject possde
un tableau dobservers
Les objets utilisent
cette interfaces pour
sinscrire comme
observer et aussi se
dsinscrire
50
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
<<interface>>
Subject
observers
registerObserver()
removeObserver()
notifyObservers()
Tous les observers potentiels doivent
implmenter linterface "Observer"
<<interface>>
Observer
Update()
Le ConcreteSubject
hrite toujours de
linterface Subject. Il
implmente la mthode
notifyObservers() qui
est sense mettre
jour lobserver quand
ltat change.
registerObserver(){}
removeObserver() {}
notifyObservers() {}
getState()
setState()
subject
ConcreteObserver
Update()
//autres mthodes
Toutes classes qui implmente lobserver est
un observer concret. Chaque observer
concret sinscrit auprs dun sujet concret
pour recevoir lupdate
51
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Station mto:
La puissance du couplage faible (13/14)
Deux objets, qui sont faiblement coupls, entrent en interaction
avec trs peu de connaissance de lun envers lautre.
Le patron Observer permet de raliser une conception ou le
Subject et lObserver sont faiblement coupls
Couplage faible : plus dindpendance et de flexibilit
ConcreteSubject
Les objets Observers
52
La seule chose que le Subject a besoin de connaitre sur lObserver est
quil implmente une certaine interface.
On peut ajouter/remplacer/supprimer un observer tout moment
sans toucher au Subject
On peut rutiliser le Subject ou lObserver facilement parcequil ne
sont pas fortement coupls.
La modification du Subject ou de lObserver naffecte pas lautre classe
Rgle 4: Opter pour une conception faiblement couple
entre les objets qui interagissent
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Station mto:
La conception finale (14/14)
<<interface>>
Subject
observers
registerObserver()
removeObserver()
notifyObservers()
WeathetData
<<interface>>
DisplayElement
<<interface>>
Observer
display()
update()
subject
registerObserver(){}
removeObserver() {}
notifyObservers() {}
getTemperature()
getHumidity()
getPressure()
measurementChanged()
Le Patron Observateur
CurrentConditionsDisplay
update()
display()
StatisticsDisplay
update()
display()
ForecastDisplay
update()
display()
Le patron de conception observateur/observable est utilis pour envoyer
un signal des modules qui jouent le rle d'observateur.
En cas de notification, les observateurs effectuent alors l'action adquate en
fonction des informations qui parviennent depuis les modules qu'ils
observent (les "observables").
Les trois afficheurs pointent sur le WeatherData afin
de permettre leur inscription et leur dsinscription
53
Rcapitulatif (1/2)
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Rcapitulatif (2/2)
Bases de lOO:
Abstraction, Encapsulation, Polymorphisme & Hritage
Principes de lOO
Encapsuler ce qui varie
Favoriser la composition sur lhritage
Programmer avec des interfaces et non des implmentations
Opter pour une conception faiblement couple entre les objets
qui interagissent
Patron de lOO
Strategy: dfinit une famille dalgorithmes interchangeables
Observer: dfinit une dpendance1--plusieurs entre objets, de
faon que pour chaque changement de ltat dun objet , ses
dpendants sont notifis et mis jour automatiquement.
55
54
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Le patron observer dfinit une relation 1--plusieurs entre
objets.
Le Subject/Observable met jour les observers travers
une interface commune.
Lobserver est faiblement coupl avec le Subject. Ce
dernier ne connait rien deux part quils implmentent
linterface Observer.
On peut rcuprer les donnes du Subject en mode
pull/push. (Le Subject fait le push, semble plus correct)
On ne dpend pas dun ordre spcifique de notification
entre les observers
Java possde plusieurs implmentations de ce patron
56
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Exercice
Exercice (1/2)
Appliquer le patron Observer sur lapplication station mto en se
basant sur les implmentations du Subject et de lObserver offertes
par Java :
1.
[Link] : Subject du patron (Attention! Il sagit dune classe)
[Link] : Observer du patron
Les mthodes getSecondes, getMinutes et getHeures permettent daccder aux
valeurs des secondes, minutes et heures respectivement. La classe Chrono est une
classe concrte implantant linterface de la classe AbstractChrono. Lorsquune
seconde passe (tick()), les Displays doivent afficher les heures, les minutes et les
secondes et les Sonneries doit faire entendre un tintement chaque heure.
Sonnerie1
<<interface>>
Observer
Pour dire
Observable
explicitement que
ltat de lobservable addObserver(Observer o)
a chang. Elle ne fait deleteObserver(Observer o)
pas la notification.
notifyObservers(Object arg)
ding()
update(Observable o, Object
arg)
Ou
o est utilis pour rcuprer le message, et
arg est un argument passer lobserver
setChanged()
Il sagit dune classe. Les mthodes
offertes sont dj implmentes.
(mettez le null, si pas besoin de passer un argument)
Sonnerie2
Expliquer comment Java utilise le patron observer pour la gestion
des vnements sur les interfaces graphiques.
2.
57
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
ding()
58
AbstractChrono
int secondes;
int minutes;
int heures;
getSecondes()
getMinutes()
getHeures()
tick()
Chrono
DisplayNumerique
afficheTempsEcoule()
DisplayAiguille
afficheTempsEcoule()
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Exercice (2/2)
Utiliser le pattern Observer pour dfinir les interactions entre Chrono, Display et
Sonnerie
Donnez le diagramme de classes et limplmentation.
public static void main(String[] args) {
Le patron
"Decorator"
Chrono c=new Chrono();
Sonnerie_Observer S1=new Sonnerie1(c);
Sonnerie_Observer S2=new Sonnerie2(c);
Display_Observer D1= new DisplayNumerique(c);
Display_Observer D2= new DisplayAiguille(c);
for(int i=1;i<5000;i++)
{ try{[Link](1000);}
catch(InterruptedException e) {[Link]("erreur");}
[Link]((i%3600)%60, (int)((i%3600)/60), (int)(i/3600)); } }
59
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
60
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
StarCoffee :
Conception (2/10)
StarCoffee :
Spcification (1/10)
Objectif: Mettre en uvre un systme de gestion des offres
de boisson pour la clientle de StarCoffee
Besoin: Dcrire les ajouts en extra, et calculer le prix total
Tea
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
StarCoffee :
Problme (3/10)
cost()
cost()
CoffeeWithMilk
cost()
63
cost()
TeaWithMintWit
hPine
cost()
Chaque sous classe implmente la mthode
cost() qui reprsente le prix du boisson
62
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
StarCoffee :
Nouvelle conception (4/10)
Problme : En plus des deux produits prsents prcdemment,
StarCoffee offre une varit dautres boissons et condiments: (Si
on offre 2 types de Th, on doit ajouter plusieurs autres classes
(selon les condiments possibles), etc.
Beverage
Description
Milk
Mint
Pine
Whip
Constat: clatement du diagramme de classes par un nombre ingrable
de classes
Beverage
Solution : Utiliser des variables
dinstance dans la supre classe qui
reprsenteront les condiments
(pignon, mousse, lait, menthe).
TeaWithMint
CoffeeWithMilk
WithWhip
cost()
[Link], [Link], [Link],
[Link], [Link], [Link],
[Link], etc.
61
Retourne la description
Coffee
Concevoir une supre classe Boisson que toutes les autres
classes hritent.
Dfinir autant de classes quil y en a de types de boissons :
Mthode abstraite dfinir
dans les classes drives
Th, Th--la-menthe, Th--la-mente-aux-pignons, etc..
Caf, Caf-au-Lait, Caf-au-Lait--la-mousse, etc..
Conception: OO
Beverage
Description
getDescription()
cost()
Description
Milk
Mint
Pine
Whip
getDescription()
cost()
hasMilk()
setMilk()
hasMint()
setMint()
hasPine()
setPine()
hasWhip()
setWhip()
Des boolans
getDescription()
cost()
hasMilk()
setMilk()
hasMint()
setMint()
hasPine()
Des get et set pour les
setPine()
booleans des condiments
hasWhip()
setWhip LOUATI [Design patterns]
Riadh BEN HALIMA&Wajdi
Dans chaque classe drive,
on ajoute les condiments
(set), puis cest la mthode
cost() qui calcule le prix
total (en vrifiant avec has)
Tea
Coffee
cost()
64
cost()
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
StarCoffee :
Un boisson dcor (5/10)
1.
On commence par lobjet Tea
Le client veut aussi des pignons, alors on cre un objet Pine qui
Lobjet Pine est un dcorateur, donc il est un
emballe le Mint
3.
La classe Tea hrite de Beverage et possde une
mthode cost() qui calcule le prix du boisson
cost()
2.
StarCoffee :
Un boisson dcor (6/10)
miroir du type Tea et inclut une mthode cost()
Le client choisit la menthe, alors on cre un objet Mint qui
enveloppe le Tea
cost()
cost()
cost()
Lobjet Mint possde une mthode cost() et travers
le polymorphisme, on peut traiter chaque Beverage
envelopp dans le Mint comme un Beverage aussi.
cost()
cost()
Lobjet Tea, envelopp dans un Mint et un Pine,
reste toujours un Beverage. Alors on peut faire
avec lui ce quon peut faire avec les Beverage, y
compris linvocation de sa mthode cost()
Lobjet Mint est un dcorateur. Son type est un
miroir de lobjet quil dcore (Beverage).
65
66
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
StarCoffee :
Le cot du boisson dcor (7/10)
StarCoffee :
Le patron Decorator (8/10)
Lide est de calculer le cot en partant du dcorateur le plus extrieur
(Pine) et puis, ce dernier dlgue le calcul lobjet dcor, etc.
Pine appelle cost() de Mint
Dfinition:
Mint appelle cost() de Tea
Invocation de la mthode
cost() du dcorateur extrieur
cost()
0.300
cost()
0.200
Decorator
Le patron decorator attache des responsabilits
additionnelles un objet dynamiquement. Les dcorateurs
offrent une alternative flexible de sous-classement afin
dtendre les fonctionnalits.
cost()
0.500
1.000
Pine ajoute son prix au rsultat de
Mint, et retourne le rsultat total: 1.000
Tea retourne son prix: 0.500
Mint ajoute son prix au rsultat de cost()
de Tea, et retourne le nouveau total: 0.700
67
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
68
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
StarCoffee :
Le diagramme de classes du patron(9/10)
Chaque composant peut tre utilis lui
seul, ou envelopp dans des dcorateurs
Component
Le ConcreteComponent est
lobjet quon va lui ajouter
dynamiquement des nouveaux
comportements. Il tend
lobjet Component.
methodA()
methodB()
//autres mthodes
Le ConcreteDecorator possde
un attribut qui reprsente lobjet
quil dcore. Il peut ajouter ses
propres mthodes et attributs.
69
Beverage agit comme notre
classe abstraite component
Coffee
Decorator
methodA()
methodB()
//autres mthodes
ConcreteDecoratorA
Component WrappedObj
methodA()
methodB()
Newbehavior()
//autres mthodes
Les dcorateurs implmentent
la mme interface (ou classe
abstraite) que lobjet quils
dcoreront
cost()
ConcreteDecoratorB
Tea
CondimentDecorator
cost()
Whip
Component WrappedObj
Object newState
methodA()
methodB()
//autres mthodes
Riadh BEN HALIMA&Wajdi
LOUATI [Design patterns]
getDescription();
Le constructeur du
dcorateur prend le
boisson dcorer en
entre et retourne le
boisson dcor.
Milk
Mint
Pine
Beverage beverage
Beverage beverage
Beverage beverage
Beverage beverage
cost()
cost()
cost()
cost()
70
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Rcapitulatif (2/2)
Bases de lOO: Abstraction, Encapsulation, Polymorphisme & Hritage
Principes de lOO
Encapsuler ce qui varie
Favoriser la composition sur lhritage
Programmer avec des interfaces et non des implmentations
Opter pour une conception faiblement couple
Les classes doivent tre ouvertes pour les extensions et fermes pour
les modifications
Patron de lOO
Strategy: dfinit une famille dalgorithmes interchangeables
Observer: dfinit une dpendance1--plusieurs entre objets.
decorator: attache des responsabilits additionnelles un objet
dynamiquement. Les dcorateurs offrent une alternative flexible de sousclassement afin dtendre les fonctionnalits.
71
Component
Les deux composants
concrets, 1 par type de boisson
Rcapitulatif (1/2)
Beverage
description
getDescription()
cost();
//autres mthodes
Chaque dcorateur possde un composant, qui veut
dire que le dcorateur possde un attribut qui contient
une rfrence dun composant
ConcreteComponent
methodA()
methodB()
//autres mthodes
StarCoffee :
La conception finale (10/10)
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Lhritage est une forme dextension, mais il nest pas ncessairement
la meilleure manire pour obtenir la flexibilit dans notre conception
Le patron decorator implique un ensemble de classes de dcorations
qui sont utilises pour envelopper les composants concrets.
Les classes dcorateurs refltent le type de composant quils
dcorent.
Les dcorateurs changent le comportement de leurs composants tout
en ajoutant des nouvelles fonctionnalits aprs/avant (ou la place de)
lappel des mthodes des composants
On peut envelopper un composant dans nimporte quel nombre de
dcorateurs
Les dcorateurs sont transparents par rapport au client du
composant
72
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Exercice (1/3)
Exercice (2/3)
Comment faire pour obtenir un caf avec "double mousse"?
StarCoffee a ajout un nouveau boisson (Citronnade) au systme,
comment procder pour linclure dans la conception actuelle?
StarCoffee veut introduire des tailles pour ses menus: SMALL,
MEDIUM et LARGE. Comment prendre en charge cette nouvelle
spcification, si la taille modifie seulement les prix des composants
concrets?
1.
2.
3.
Avec le patron decorator, le package [Link] doit donner plus de
sens, puisquil se base largement sur ce patron.
FileInputStream est un composant
dcor. Le package [Link] offre plusieurs
objets pour la lecture des octets:
FileInputStream,
StringBufferInputStream,
ByteArrayInputStream, etc.
LineNumberInputStream est aussi
un dcorateur concret. Il ajoute la
capacit de compter les nombres
de lignes en lisant les donnes.
73
74
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
BufferedInputStream est un dcorateur concret. Il
ajoute deux comportements: (i) il tamponne les
entres afin damliorer la performance, et (ii)
ajoute la mthode readLine() pour lire une ligne de
caractres la fois.
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Exercice (3/3): Dcoration de [Link]
Ecrire un dcorateur qui convertit tous les caractres majuscules
en minuscules dans le flux dentre (InputStream).
1.
Abstract Component
Conctrete
Component
InputStream
FileInputStream
Abstract Decorator
StringBufferInputStream
FilterInputStream
ByteArrayInputStream
PushBackInputStream
BufferedInputStream
Decorator
DataInputStream
75
LineNumberInputStream
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Lobjectif de cet exercice est de mettre en uvre un
systme flexible de gestion des offres de voiture pour la
clientle de StarCar. Le besoin de cette socit se rsume
dcrire les options demandes par le client (VitreElectrique,
AirBag et ABS) et inclure son cout au prix total de la
voiture choisie. Deux types de voiture sont grs par la
socit, savoir, camionnette et berline. Chaque voiture est
caractrise par un cout et une description textuelle. Le
prix de chaque type de voiture ainsi que celui de chaque
option est fixer au moment de la cration.
En utilisant le patron Decorator, donnez le diagramme de
classes de lapplication CarStar. (Prcisez les mthodes et
les attributs, correspondant au bout de code ci-dessous)
76
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
public static void main(String[] args) {
Voiture v1=new Camionnette ("P404",10000);
Voiture v2=new Berline ("P407",20000);
Le patron
"Adapter"
v1=new ABS(v1, 800);//800 reprsente le prix de loption ABS
v2=new VitreElectrique(v2, 1000); // 1000 reprsente le prix de loption
v2=new AirBag(v2, 1200); // 1200 reprsente le prix de loption
[Link]("La voiture est une "+[Link]());
//affiche: La voiture est une P404 avec ABS
[Link]("Son prix est:"+ [Link]());
//affiche: Son prix est 10800
[Link]("La voiture est une "+[Link]());
//affiche: La voiture est une P407 avec VitreElectrique, AirBag
[Link]("Son prix est:"+ [Link]());
//affiche: Son prix est 22200
77
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
78
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Le patron adapter :
Les adaptateurs dans lOO (2/7)
Le patron adapter :
Les adaptateurs (1/7)
Notre
systme
existant
Prise Europenne
Adaptateur
Linterface ne correspond par ce quon a dj cod.
a ne va pas march!
(supposant quon ne peut pas changer de vendeur)
Cble American du PC
Notre
systme
existant
Ladaptateur convertit une
interface une autre
Mme code
79
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Classe du
vendeur
80
Adaptateur
Nouveau code
Classe du
vendeur
Mme code
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Le patron adapter :
Dinde et Canard (3/7)
Supposant que le dinde marche et cancane comme le canard
Un canard peut cancaner et voler
interface Duck{
void quack();
void fly();
}
interface Turkey{
void gobble();
void fly();
}
81
Une simple implmentation du comportement du canard
Supposons quon a un manque de canards et on va utiliser des
dindes leur pace Il faut crire un "adapter"
Respecter linterface des canards
class MallardDuck implements Duck{
public void quack(){
[Link]("Quack");}
public void fly(){
[Link]("Fly");}
}
class TurkeyAdapter implements Duck{
Turkey turkey;
TurkeyAdapter(Turkey turkey){
[Link]=turkey;}
Une rfrence vers lobjet adapter
public void quack(){
[Link]();
}
public void fly(){
for(int i=0;i<5;i++)
[Link]();
}
}
Le dinde ne cancane pas, mais glougloute
Le dinde peut voler (courte distance)
class WildTurkey implements Turkey{
public void gobble(){
[Link]("Gobble");}
public void fly(){
[Link]("Fly for a short distance");}
}
82
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Le patron adapter :
Testons ladaptateur(5/7)
public class TestAdapter{
public static voir main (String arg[])
{
MallardDuck mallard= new MallardDuck();
WildTurkey wild = new WildTurkey();
Duck turkeyAdapter = new TurkeyAdapter(wild);
test(mallard);
test(turkeyAdapter);
}
static void test(Duck duck)
{
[Link]();
[Link]();
}
}
Le patron adapter :
Ladaptateur du dinde(4/7)
Translation des mthodes
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Le patron adapter (6/7)
Dfinition:
Adapter
Le patron Adapter convertit linterface dune classe
une autre interface que le client attend. Les adaptateurs
permettent aux classes, aillant des interfaces incompatibles,
de travailler ensemble.
Donner le rsultat dexcution de cette classe
83
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
84
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Le patron adapter (6/7)
Adapter :
Le diagramme de classes du patron (7/7)
Client
<<interface>>
Target
LAdapter implmente
linterface Target
Request()
Le client voit seulement
linterface Target.
Adapter
Adaptee
Request()
specificRequest()
Ladapter est compos
dun Adaptee
85
86
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Toutes les requtes sont
dlgues Adaptee
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Le patron Facade:
Dmarrer un home-cinma (1/4)
Tuner
Dmarrer le HC: amplifier
on()
baisser la lumire off()
setAm()
allumer lcran
setFM()
dmarrer lampli
dmarrer le DvDplayer
le brancher avec lmpli
jouer le DvD
etc..
Le patron
"Faade"
87
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
88
Amplifier
tuner
dvdPlayer
.
on()
off()
setCD()
setDVD()
DVDPlayer
amplifier
on()
off()
play()
stop()
pause()
Screen
up()
down()
Et bien dautres classes
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Le patron Facade:
Les classes dun Home cinma (2/4)
La Faade: une nouvelle
classe pour le
HomeCinema avec peu
de mthode
Tuner
amplifier
on()
off()
setAm()
setFM()
CDPlayer
WatchDVD()
HomeCinema
WatchTV()
WatchDVD()
.
Dfinition:
Amplifier
DVDPlayer
tuner
dvdPlayer
.
amplifier
on()
off()
play()
stop()
pause()
on()
off()
setCD()
setDVD()
amplifier
on()
off()
play()
stop()
89
pause()
Le patron faade (3/4)
Le client invoque les
mthodes sur la Faade
Faade
Le patron Faade prsente une interface unifie pour un
ensemble de sous-interfaces dans un systme. La faade
dfinit une interface de haut niveau qui rend facile
lutilisation du systme.
La classe Faade traite les
composants du
HomeCinema comme des
sous-systmes quil invoque
pour implmenter ses
mthodes
Projector
Screen
on()
off()
up()
down()
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Faade:
Le diagramme de classes du patron (4/4)
90
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Testons nos connaissances!
Une interface unifie et
simple utiliser
Client
Faade
Patron
Un client heureux car
son travail devient
facile grce la faade
Les classes des sous-systmes
Systmes complexes
91
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Rle
Decorator
Convertit une interface en une
autre
Adapter
Ne modifie pas linterface,
mais ajoute des responsabilits
Facade
Rend les interfaces simples
92
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Singleton :
Spcification (1/12)
Objectif: Crer un type dobjet pour lequel on cre
seulement une seule instance
Cest le patron ayant le diagramme de classes le plus simple
Il y a plusieurs objets dont on a besoin dune seule instance:
pool dimpression, boite de dialogue, objet qui manipule les
prfrences, objet de logging, objet agissant comme pilote de
carte graphique/imprimante
La cration de plus dune instance de ces objets est une
source de problme, telle que la sur-utilisation des
ressources, des comportements incorrectes de programme,
des rsultats inconsistants, etc.
Le patron
"Singleton"
93
Singleton :
Crer un singleton (2/12)
static
Que signifie ce code.
Oui
Si on met les choses ensemble, est ce quon peut instancier
MonObjet?
public class MonObjet{
Cest une classe qui ne peut pas tre instancie,
car elle possde un constructeur priv
public class MonObjet{
private MonObjet() {}
}
private MonObjet(){ }
public static MonObjet getInstance() {
return new MonObjet();
}
Qui peut utiliser ce constructeur?
Le code de MonObjet est le seul code qui peut lappeler (dans une mthode)
95
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
public class MonObjet{
public static MonObjet getInstance() {
}
}
Cest une mthode statique qui peut tre appele partir du nom de la
classe : [Link]()
Oui (il faut que la classe soit publique)
Que signifie ce code ?
New MonObjet()
Pour toute classe, est ce quon peut linstancier plus quune fois?
Comment je peux appeler cette mthode (pour crer une
instance) si je nai pas dinstance?
Et si un autre objet veut crer un MonObjet? Est-ce quil peut
appeler new sur MonObjet une autre fois?
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Singleton :
Crer un singleton (3/12)
Comment crer un seul objet?
94
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Comment faire pour crer une seule instance?
96
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Singleton :
Implmentation du patron (4/12)
Nous avons une variable statique
pour stocker notre instance
public class Singleton {
private static Singleton uniqueInstance;
private Singleton() {}
public static Singleton getInstance(){
if (uniqueInstance == null)
uniqueInstance = new Singleton();
Le constructeur est dclar priv.
Seulement la classe Singleton qui
peut instancier cette classe
Cette mthode nous offre une manire
pour instancier la classe Singleton
return uniqueInstance;
}
Si uniqueInstance nest pas nul, a veut dire
quelle a t cre prcdemment
public static void main(String args[]) {
Singleton s= [Link]();
}
}
97
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Singleton :
Lusine de chocolat (6/12)
Singleton :
Lusine de chocolat (5/12)
public class ChocolateBoiler{
private boolean empty;
Le code dmarre lorsque
private boolean boiled;
la casserole est vide
public ChocolateBoiler() {
empty=true; boiled=false;
Pour remplir la casserole, elle
}
doit tre vide. Lorsquelle est
public void fill(){
pleine, on met empty false.
if (empty){
//remplir la casserole avec du lait/chocolat
empty=false; boiled=false;
}
Pour vide la casserole, elle doit
}
public void drain(){
tre pleine et dj mixe. une
if (!empty && boiled){
fois vide, on met empty true.
//vider la casserole
empty=true;
}
}
Pour mixer le contenu de la
public void boil(){
casserole, elle doit tre pleine et
if (!empty && !boiled){
non dj mixe. Lorsquelle est
//faire bouillir
boiled=true;
pleine, on met boiled true.
}
}
}
98
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Singleton :
Le patron Singleton(7/12)
Amliorer le code de lusine de chocolat en le transformant en Singleton
public class ChocolateBoiler {
private boolean empty;
private boolean boiled;
private static ChocolateBoiler uniqueInstance;
Dfinition:
Singleton
Le patron Singleton assure une seule instance pour une
classe, et offre un point daccs global cette classe.
private ChocolateBoiler() {
empty=true; boiled=false;
}
public static ChocolateBoiler getInstance() {
if (uniqueInstance == null)
uniqueInstance = new ChocolateBoiler();
return uniqueInstance;
}
//reste du code
}
99
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
100
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Singleton:
Le diagramme de classes du patron (8/12)
Singleton :
Problme des threads (9/12)
Supposant que nous avons deux threads qui vont excuter la mthode
getInstance(). Est-ce quil y a un cas o on cre 2 instances?
Thread-1
La variable de classe uniqueInstance
tient la seule instance du Singleton
public static ChocolateBoiler
getInstance()
Singleton
if (uniqueInstance == null)
+ static getInstance()
//autre mthodes utiles
101
La mthode getInstance() est statique.
Cest une mthode de classe quon peut
y accder partout dans le code avec
[Link](). Il sagit dune
instanciation facile de cette classe
uniqueInstance = new
ChocolateBoiler();
return uniqueInstance;
Singleton :
Gestion du multi-threading (10/12)
Solution 1: synchroniser laccs la mthode getInstance()
Object1
return uniqueInstance;
102
null
Object1
uniqueInstance = new
ChocolateBoiler();
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
null
null
if (uniqueInstance == null)
//autre donnes utiles
Valeur de
UniqueInstance
null
public static ChocolateBoiler
getInstance()
- static uniqueInstance
Thread-2
Object2
Object2
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Singleton :
Gestion du multi-threading (11/12)
Solution 2: cration au moment de la dfinition de la variable de classe
Initialisation par le JVM avant accs des threads
public class Singleton {
private static Singleton uniqueInstance;
private Singleton() {}
public class Singleton {
private static Singleton uniqueInstance = new Singleton();
Un seule thread peut accder,
la fois, cette mthode
private Singleton() {}
public static synchronized Singleton getInstance(){
if (uniqueInstance == null)
uniqueInstance = new Singleton();
return uniqueInstance;
}
//autre mthodes utiles
public static Singleton getInstance(){
return uniqueInstance;
Il y a dj une instance, il faut
}
juste la retourner
//autre mthodes utiles
}
Inconvnient: synchronized rduit la performance dun facteur de 100
Si la mthode getInstance() nest pas critique pour notre application, on peut
se contenter de cette solution
103
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
La JVM cre une instance de Singleton lors du chargement de la classe. La JVM
garantit que linstance va tre cre avant que les threads accdent la variable
statique uniqueInstance.
104
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Singleton :
Gestion du multi-threading (12/12)
Solution 3: rduire lutilisation de la synchronisation dans getInstance()
Le mot cl volatile assure que les threads grent la variable
uniqueInstance correctement au moment de son initialisation
Rcapitulatif (1/2)
public class Singleton {
private volatile static Singleton uniqueInstance;
private Singleton() {}
public static Singleton getInstance(){
if (uniqueInstance == null) {
synchronized([Link]) {
if (uniqueInstance == null)
uniqueInstance = new Singleton();
}
}
return uniqueInstance;
}
//autre mthodes utiles
On synchronise seulement la
premire fois
Bases de lOO: Abstraction, Encapsulation, Polymorphisme & Hritage
Principes de lOO
Encapsuler ce qui varie
Favoriser la composition sur lhritage
Programmer avec des interfaces et non des implmentations
Opter pour une conception faiblement couple
Les classes doivent tre ouvertes pour les extensions et fermes pour les
modifications
Dpendre des abstractions. Ne jamais dpendre de classes concrtes
Patron de lOO
Strategy: dfinit une famille dalgorithmes interchangeables
Observer: dfinit une dpendance1--plusieurs entre objets.
decorator: attache des responsabilits additionnelles un objet dynamiquement.
Abstract Factory: offre une interface de cration de familles dobjets
Factory Method: dfinit une interface de cration des objets
Singleton: assure une classe une seule instance et lui offre un point daccs global
*volatile: inclus java depuis jdk5
105
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
106
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Rcapitulatif (2/2)
Le patron singleton assure la cration dau plus une instance dune
classe de notre application
Le patron offre aussi un seul point daccs global cette instance
Limplmentation Java du patron utilise un constructeur priv une
mthode statique combine avec une variable statique
Le dveloppeur examine la performance et les contraintes des
ressources et choisit soigneusement une implmentation pour une
application multi-thread
107
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Le patron
"Command"
108
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Home-Automation :
Spcification (1/28)
Home-Automation :
Analyse du contrleur distant (2/28)
Objectif: Mettre en uvre un systme de contrle distant
dun ensemble dappareils dans une maison
Besoin: programmer les fonctionnalits dun contrleur
distant (avec 7 slots) selon des classes (prdfinies par le
vendeur) de gestion des appareils installs dans la maison.
Conception: OO
Prvoir les relations entre les boutons du contrleur distant
(ON-OFF) avec les fonctionnalits des appareils installs:
setTemperature(), setVolume(), setDirection(), etc..
Il y a des boutons on et off
pour chaque slot
Ces deux boutons ont utiliss
pour contrler la tlvision
Il y a 7 slots programmer.
On met un appareil diffrent
dans chaque slot, et on le
contrle travers les boutons
Ces deux boutons ont utiliss
pour contrler la chaine Streo,
etc
Contrleur distant
109
Home-Automation :
Les classes du vendeur (3/28)
Stereo
on()
off()
setCD()
setRadio()
setVolume()
Appliance
openValue()
closeValue()
on()
off()
setDuskTime()
setDawnTime()
manualOn()
manualOff()
AirCondition
setTemperature()
Security
Light
on()
off()
GardenLight
Faucet
CeilingLight
on()
off()
dim()
GarageDoor
up()
down()
stop()
lightOn()
lightOff()
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Home-Automation :
Discussion de la conception (4/28)
Les classes du vendeur nous donnent une ide sur les fonctionnalits
des appareils installs dans la maison :
111
110
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Un bouton global UNDO
pour annuler laction du
dernier bouton activ
arm()
desarm()
On sattendait des classes avec des mthodes on()-off()
pour bien correspondre avec le contrleur distant
Cest important de voir a comme sparation des
proccupation : le contrleur doit savoir comment
interprter lappui sur le bouton et crer des requtes, mais
il ne doit pas connaitre beaucoup sur les appareils et leurs
manires de fonctionnement (comment allumer une lampe)
OutDoorLight
on()
off()
En dautre terme, le contrleur met des requtes gnriques
Une entit prendra en charge la transformation de cette requte
en action
Sprinkler
waterOn()
waterOff()
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
112
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Home-Automation :
Discussion de la conception (4/28)
Comment mettre des requtes des objets
Order
sans rien connatre des oprations demandes ?
ou sans rien connatre de celui qui la requte est destine ?
Dissocier (dcoupler) lobjet qui invoque une opration de
lobjet qui possde les connaissances ncessaires pour
raliser cette opration.
Command :
Commander un dner (5/28)
En dautre terme, le contrleur met des requtes gnriques
Une entit prendra en charge la transformation de cette requte
en action
Le client donne sa
commande la serveuse
Waitress
Customer
La serveuse rcupre la
commande et la met sur le
comptoir, et la lance
Utiliser le patron Command
Objet Command: Encapsuler une requte sous forme dobjet
Le cuisinier prpare le
repas selon la commande
Order-Cook
113
Command :
Etudes des interactions (6/28)
createOrder()
Il y a toutes les
instructions
ncessaires pour
prparer le repas
Je veux
un burger,
un shake et
des frites
La commande (papier) est une requte pour prparer le repas
takeOrder()
La serveuse rcupre la
commande et la met sur le
comptoir, et la lance
makeBurger(), makeShake(), makeShips()
Le cuisinier suit
les instructions
de la commande
output()
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Command :
Les rles et les responsabilits (7/28)
orderUp()
115
114
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
La tche de la serveuse est de prendre la commande et dinvoquer
la mthode orderUp() dessus
Sil sagit dun objet, il peut tre pass de la serveuse au comptoir
Son interface consiste une seule mthode orderUp(), qui encapsule les actions
ncessaires pour prparer le repas
La serveuse na besoin de savoir comment prparer le repas!
La mthode takeOrder() de la serveuse peut tre paramtre avec diffrentes
commandes de plusieurs clients. Ceci ne la drange pas car elle sait que orderUp()
supporte sa commande
Le cuisinier possde les connaissances ncessaires pour prparer le
repas
Suite linvocation de orderUp(), le cuisinier implmente toutes les mthodes
ncessaires pour crer le repas
Noter quil est compltement dcoupl de la serveuse
116
La serveuse encapsule les dtails du repas dans la commande
Le cuisinier prend ses instructions de la commande, et il na pas besoin de la contacter
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Command :
Du dner vers le patron Commande (8/28)
public void execute(){
receiver.action1();
receiver.action2();
}
Lobjet Command offre une
seule mthode execute()
qui encapsule les actions
Le client cre la commande.
La commande consiste un
ensemble dactions et un receveur
action1()
action2()
..
Dner
create
Command
Object
createCommandObject( )
execute()
Command :
Correspondance (9/28)
setCommand()
setCommand()
Plus tard, le client
demande linvoker
dexcuter sa commande
execute()
execute()
action1(), action2()
Linvoker appelle la mthode
execute() de lobjet Command
117
action1()
action2()
..
de ceci rsulte
linvocation des
actions sur le
Receiver
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Command :
Le patron Command (10/28)
Command Pattern
Serveuse
(Waitress)
Command
Cuisinier
(Order-Cook)
execute()
orderUp()
Client
Commande
(Order)
invoke
Client
(Customer)
Receiver
takeOrder()
setCommand()
118
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Home-Automation :
Des Commandes (11/28)
Une requte encapsule
Dfinition:
Command
action()
Le patron Command encapsule une requte comme un
objet, ainsi il nous permet de paramtrer dautres objets
avec diffrentes requtes, files dattentes ou longues
requtes, et supporte lannulation dune opration
execute()
execute(){
[Link]()
}
execute()
119
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
execute()
120
execute()
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Command :
Le diagramme de classes du patron (12/28)
Le client est responsable de
crer une ConcretCommand
et affecter son Receiver
Client
Linvoker tient la commande et
un certain moment demande
la commande de raliser une
requte en excutant sa
mthode execute()
Interface de tous les commandes.
La commande est invoque travers
sa mthode excute, qui demande
au Receiver de raliser des actions
<<interface>>
Command
Invoker
setCommand()
public interface Command{
public void execute();
}
Implmentons une Commande pour allumer la lumire
Light
on()
off()
public class LightOnCommand implements Command {
Light light;
public LightOnCommand(Light light){
[Link] = light;
}
public void execute(){
[Link]();
}
}
ConctretCommand
action()
execute()
undo()
Le Receiver connait comment raliser le
travail demand afin de satisfaire la requte.
public void execute(){
[Link]();
}
Le ConcretCommand dfinit une lisaison
BEN
HALIMA&Wajdi LOUATI [Design patterns]
entre une actionRiadh
et un
Receiver
121
Implmentons linterface Command
execute()
undo()
Receiver
Home-Automation :
Notre premier objet Commande (14/28)
Home-Automation :
Notre premier objet Commande (13/28)
Utilisons lobjet Commande
122
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Home-Automation :
Notre premier objet Commande (15/28)
Testons la fonctionnalit du contrleur distant
public class SimpleRemoteControl{
Command slot;
public class RemoteControlTest{
public static void main(String argv[]) {
SimpleRemoteControl remote = new SimpleRemoteControl();
Light light=new Light();
LightOnCommand lightOn=new LightOnCommand (light);
public SimpleRemoteControl() {}
public void setCommand(Command command ){
slot=command;
}
[Link](lightOn); //passer la commande linvoker
[Link](); //simuler lappui sur le bouton
public void buttonWasPressed(){
[Link]();
}
123
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
124
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Home-Automation :
2me Commande (16/28)
Home-Automation :
Une autre Commande (17/28)
Dvelopper la classe GarageDoorOpenCommand
GarageDoor
public class RemoteControlTest{
public static void main(String argv[]) {
SimpleRemoteControl remote = new SimpleRemoteControl();
Light light = new Light();
LightOnCommand lightOn=new LightOnCommand(light);
up()
down()
stop()
lightOn()
lightOff()
public class GarageDoorOpenCommand implements Command {
GarageDoor garageDoor;
public GarageDoorOpenCommand (GarageDoor garageDoor){
[Link] = garageDoor;
}
public void execute(){
[Link]();
[Link]();
}
}
125
Ajoutant cette commande au slot du contrleur distant
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
GarageDoor garageDoor = new GarageDoor();
GarageDoorOpenCommand garageOpen = new
GarageDoorOpenCommand(garageDoor);
[Link](lightOn); //encapsuler la commande
[Link](); //allumer la lumire
[Link](garageOpen); //encapsuler la commande
[Link](); //ouvrir la porte du garage
}
126
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Home-Automation :
Le diagramme de classes (19/28)
Home-Automation :
Le contrleur distant (18/28)
execute()
execute()
Le client
Light
Garage
Door
execute()
execute()
RemoteLoader
Stereo
RemoteControl
onCommands
offCommands
<<interface>>
Command
execute()
setCommand()
onButtonWasPushed()
offButtonWasPushed()
execute()
execute()
Light
Les actions de la mthode execute()
sont invoques sur le Receiver
Linvoker
127
Contrleur distant
on()
off()
off()
on()
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
128
LightOnCommand
execute()
LightOffCommand
public void execute(){
execute()
[Link]();
public void execute(){
}
[Link]();
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
}
Home-Automation :
Programmer le contrleur distant (20/28)
class RemoteControl{
Command onCommands[];
Command offCommands[];
public RemoteControl() {
onCommands = new Command[7];
offCommands = new Command[7];
Eviter la gestion de null
Command noCommand = new NoCommand();
for(int i=0;i<7;i++){
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
}
public void setCommand(int slot, Command onCommand,Command offCommand ){
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
}
public void onButtonWasPressed(int slot){
onCommands[slot].execute();
}
public void offButtonWasPressed(int slot){
offCommands[slot].execute();
}
public String toString(){
String s="";
for(int i=0;i<7;i++){
s+="Slot["+i+"] "+onCommands[i].getClass().getName() +"
"+offCommands[i].getClass().getName()+"\n";
} return s;
}}
129
class RemoteLoader{
public static void main(String arg[]){
RemoteControl remoteControl = new RemoteControl();
Light livingRoomLight=new Light();
LightOnCommand livingRoomLightOnCommand = new
LightOnCommand(livingRoomLight);
LightOffCommand livingRoomLightOffCommand = new
LightOffCommand(livingRoomLight);
[Link](0, livingRoomLightOnCommand,livingRoomLightOffCommand);
[Link](0);
[Link](0);
Stereo stereo = new Stereo();
StereoOnWithCDCommand stereoOnWithCDCommand = new
StereoOnWithCDCommand(stereo);
StereoOffCommand stereoOffCommand = new StereoOffCommand(stereo);
[Link](1,stereoOnWithCDCommand,stereoOffCommand);
[Link](1);
[Link](1);
[Link]([Link]());
}
}
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Programmer les classes suivantes:
[Link], [Link]
LightOnCommand,.java [Link],
[Link], [Link]
class LightOnCommand
implements Command {
Light light;
public LightOnCommand(Light
light){
[Link] = light;
}
public void execute(){
[Link]();
}
}
130
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Home-Automation :
Tester le contrleur (22/28)
131
Home-Automation :
Programmer les commandes (21/28)
class StereoOnWithCDCommand
implements Command {
Stereo stereo;
public StereoOnWithCDCommand(Stereo
stereo){
[Link] = stereo;
}
public void execute(){
[Link]();
[Link]();
[Link](11);
}
}
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Home-Automation :
Undo: Annuler la dernire opration (23/28)
Implmentons linterface Command
public interface Command{
public void execute();
public void undo();
}
Implmentons une Commande pour allumer la lumire
public class LightOnCommand implements Command {
Light
Light light;
on()
public LightOnCommand(Light light){
off()
[Link] = light;
}
public void execute(){
[Link]();
}
public void undo(){
Opration excuter en cas
[Link]();
dannulation de cette commande
}
}
132
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Home-Automation :
Undo: Annuler la dernire opration (24/28)
class RemoteControl{
Command onCommands[];
Command offCommands[];
Cest ou on stockera la dernire
Command undoCommand;
commande excute pour le bouton undo
public RemoteControl() {
onCommands = new Command[7];
offCommands = new Command[7];
Command noCommand = new NoCommand();
for(int i=0;i<7;i++){
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
Initialisation NoCommand afin
undoCommand = noCommand; }
dviter le traitement de null
public void onButtonWasPressed(int slot){
onCommands[slot].execute();
undoCommand = onCommands[slot];
}
Enregistrer la dernire commande
public void offButtonWasPressed(int slot){
offCommands[slot].execute();
undoCommand = offCommands[slot];
}
Lorsquon appuie sur le bouton undo, on
public void undoButtonWasPressed(){
invoque la mthode undo() pour annuler
[Link]();
}
la dernire commande excute
} 133
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Home-Automation :
La Macro-Commande (26/28)
Cest le regroupement de plusieurs commandes en une seule
public class MacroCommand implements Command {
Stocker les commandes
Command [] commands;
de la macro-commande
public MacroCommand (Command [] commands){
[Link] = commands;
Un boucle pour excuter
}
toutes les commandes de la
public void execute(){
macro-commande
for (int i=0;i<[Link];i++)
commands[i].execute();
}
}
Crer les commandes mettre dans la macro-commande
LightOnCommand lightOnCommand = new LightOnCommand(light);
StereoOnWithCDCommand stereoOnWithCDCommand = new
StereoOnWithCDCommand(stereo);
TVOnCommand tvOnCommand = new TVOnCommand(tv);
Crer les commandes
//crer aussi les Off-Commandes
135
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Home-Automation :
Tester le contrleur avec UNDO (25/28)
Annuler lallumage de la lumire
class RemoteLoader{
public static void main(String arg[]){
//
[Link](0);
[Link]();
//
[Link](1);
[Link](1);
[Link]([Link]());
}
}
134
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Home-Automation :
MacroCommand (27/28)
Crer les macro-commandes
Command [] on = {lightOnCommand, stereoOnWithCDCommand, tvOnCommand};
Command [] off = {lightOffCommand, stereoOffWithCDCommand, tvOffCommand};
MacroCommand onMacro= new MacroCommand(on);
MacroCommand offMacro= new MacroCommand(off);
Les commandes sous
formes de tableau
Affecter les macro-commandes un bouton
[Link](2, onMacro, offMacro);
Affecter les macro-commandes
au bouton du slot n2
Excuter la macro-commande
[Link]("Macro On");
[Link](2);
[Link]("Macro Off");
[Link](2);
136
Tester ces macro-commandes et
donner le rsultat de lexcution
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Autre utilisation du patron Command :
Organiser les queues de requtes (28/28)
Les commandes nous offrent une manire de
paquetage les morceaux de calcul (computation).
Les calculs (commandes cres par des applications)
seront placs dans des queues (queue de jobs) pour
tre excuts.
Rcapitulatif (1/2)
Bases de lOO: Abstraction, Encapsulation, Polymorphisme & Hritage
Principes de lOO
Encapsuler ce qui varie
Favoriser la composition sur lhritage
Programmer pour des interfaces
Opter pour une conception faiblement couple
Les classes doivent tre ouvertes pour les extensions et fermes pour les
modifications
Dpendre des abstractions. Ne jamais dpendre de classes concrtes
Patron de lOO
Strategy: dfinit une famille dalgorithmes interchangeables
Observer: dfinit une dpendance1--plusieurs entre objets.
Decorator: attache des responsabilits additionnelles un objet dynamiquement.
Abstract Factory: offre une interface de cration de familles dobjets
Factory Method: dfinit une interface de cration des objets
Singleton: assure une classe une seule instance
Command: encapsule une requte comme un objet
execute()
execute()
execute()
execute()
execute()
Les threads rcuprent les commandes
de la queue une une, et appellent leur
mthode execute(). Une fois complt,
ils retournent pour une nouvelle
commande.
137
Cest une manire efficace
pour limiter le calcul un
nombre fix de Threads
execute()
execute()
138
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Rcapitulatif (2/2)
Exercice 1
Le patron Command dcouple un objet, faisant des requtes, de lobjet
qui sait comment la raliser
Un objet Command est au centre de ce dcouplage et encapsule le
Receiver avec une action (ou des actions)
LInvoker excute la requte dun objet Command en appelant sa
mthode execute(), qui invoque les actions sur le Receiver
Le patron Command supporte lannulation (undo) par limplmentation
dune mthode undo() -dans la commande- qui restore lancien tat du
systme (avant lexcution de la mthode execute())
Les Macro-Commandes sont des simples extensions de Command qui
permettent linvocation de multiple commandes. Pareil, les macrocommandes peuvent supporter les mthodes dannulation (undo).
Le patron Command est utilis aussi pour implmenter lorganisation
des requtes (Jobs) et la gestion de la journalisation (logging)
139
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
On vous demande de participer la cration dun nouvel outil graphique. Cet
outil permettra de crer de manire intuitive des dessins avec un niveau de
complexit plus ou moins lev. Les dessins pourront tre composs dun
ensemble de points, droites, arc de cercles ou autres formes simples telles que
des cercles ou des polygones. Cet outil sera similaire au programme appel
Paint sous lenvironnement Windows. La figure suivante prsente un
diagramme de classes simplifi pour cette application :
Application
Vous tes charg de concevoir le mcanisme
qui permettra de garder une trace des actions
de lutilisateur. Ce dernier pourra ainsi annuler
les dernires actions faites.
Question: Faites les modifications ncessaires
au diagramme de classes pour implanter le
patron Commande.
+ouvrir(doc:Dessin)
+fermer()
+sauvegarder():boolean
Dessin
+ajouterPoint(position:Vecteur2D)
+ajouterDroite(pt1:Vecteur2D,pt2:Vecteur2D)
+ajouterCercle(rayon:float,centre:Vecteur2D)
+ajouterPolygone(listePts:[]Vecteur2D)
+afficher()
140
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Exercice 2
Le but de cet exercice est de tester la puissance du pattern Command. Pour ce
faire, nous disposons dune calculatrice offrant les oprations arithmtiques de
base (+, - et *) sur 2 rels et nous voulons transformer les actions (des
utilisateurs) de calculs sur cette calculatrice en des commandes.
Le Modle-VueContrleur
1. Donne le digramme de classes dcrivant cette transformation avec le pattern
Command.
2. Implanter ce diagramme tout en respectant le client suivant :
public class Client {
public static void main(String[] args) {
Calculatrice c=new Calculatrice();
PlusCommand plus =new PlusCommand(c);
MultipCommand mult=new MultipCommand (c);
SoustCommand sous =new SoustCommand(c);
CalculatriceControl control =new CalculatriceControl();
[Link](0, plus);
[Link](1, sous);
[Link](2, mult);
[Link](2, 5, 15);
[Link](1, 17, 10);
[Link](0, 12, 15); }}
141
142
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Architecture Modle/Vue/Contrleur
Le modle MVC: destin rpondre aux besoins des applications
interactives en sparant les problmatiques lies aux diffrents
composants au sein de leur architecture respective.
Ce paradigme regroupe les fonctions en trois catgories :
un modle (modle de donnes),
une vue (prsentation, interface utilisateur)
un contrleur (logique de contrle, gestion des vnements, synchronisation)
Le Modle
143
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Le modle reprsente le cur (algorithmique) de l'application :
traitements des donnes, interactions avec la base de donnes, etc.
L'ide est de bien sparer les
donnes, la prsentation et les
traitements.
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
dcrit les donnes manipules par l'application.
regroupe la gestion de ces donnes et est responsable de leur intgrit.
La base de donnes sera l'un de ses composants.
Le modle comporte des mthodes standards pour mettre jour
ces donnes (insertion, suppression, changement de valeur).
Les rsultats renvoys par le modle ne s'occupent pas de la
prsentation.
Le modle ne contient aucun lien direct vers le contrleur ou la vue.
Sa communication avec la vue s'effectue au travers du patron
Observateur.
144
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
La Vue
Le Contrleur
Ce avec quoi l'utilisateur interagit se nomme prcisment la vue.
prsenter les rsultats renvoys par le modle.
recevoir toute action de l'utilisateur (hover, clic de souris, slection d'un bouton radio,
cochage d'une case, entre de texte, de mouvements, de voix, etc.).
Ces diffrents vnements sont envoys au contrleur.
La vue n'effectue pas de traitement,
afficher les rsultats des traitements effectus par le modle et interagir avec
l'utilisateur.
Plusieurs vues peuvent afficher des informations partielles ou non d'un mme
modle.
145
146
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Flux de traitement
Le contrleur prend en charge la gestion des vnements de
synchronisation pour mettre jour la vue ou le modle
reoit tous les vnements de l'utilisateur et enclenche les actions
effectuer
Si une action ncessite un changement des donnes, le contrleur
demande la modification des donnes au modle, et ce dernier notifie la
vue que les donnes ont chang pour qu'elle se mette jour.
D'aprs le patron de conception observateur/observable, la vue
est un observateur du modle qui est lui observable
Le contrleur n'effectue aucun traitement, ne modifie aucune donne.
Il analyse la requte du client et se contente d'appeler le modle adquat et de
renvoyer la vue correspondant la demande.
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Architecture MVC ou 3-Tier
lorsqu'un client envoie une requte l'application :
la requte envoye depuis la vue est analyse par le contrleur (par
exemple un clic de souris pour lancer un traitement de donnes) ;
le contrleur demande au modle appropri d'effectuer les traitements et
notifie la vue que la requte est traite (via par exemple un callback) ;
la vue notifie fait une requte au modle pour se mettre jour (par exemple
affiche le rsultat du traitement via le modle).
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
le flux de contrle traverse le systme de haut en bas
Dans le modle MVC, la vue peut consulter directement le modle (lecture)
sans passer par le contrleur. Par contre, elle doit ncessairement passer
par le contrleur pour effectuer une modification (criture).
147
L'architecture trois tiers est un modle en couches, c'est--dire, que chaque
couche communique seulement avec ses couches adjacentes
le contrleur peut alors envoyer des requtes toutes les vues de manire ce
qu'elles se mettent jour.
La diffrence fondamentale se trouve dans le fait que l'architecture 3-Tier
spare la couche mtier de la couche accs aux donnes.
Pour qu'une application MVC soit une vraie application 3-Tier il faut lui ajouter une
couche d'abstraction d'accs aux donnes de type DAO (Data Access Object).
Inversement pour qu'une application 3-Tier respecte MVC il faut lui ajouter une
couche de contrle entre la couche mtier et la couche prsentation.
148
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Crer des pizzas (1/37)
Pizzeria: Crer des pizzas
Pizza orderPizza(){
Pizza pizza=new Pizza();
Le patron
"Factory"
Pour la flexibilit, on veut que
celui-ci soit une classe abstraite ou
interface, sauf quon ne peut pas
instancier lun des deux derniers!
[Link]();
[Link]();
[Link]();
[Link]();
return pizza;
}
149
150
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Plusieurs types de pizza (2/37)
On passe le type du pizza travers
le mthode orderPizza()
Pizza orderPizza( String type ){
Pizza pizza;
Selon le type de pizza, on cre la
pizza concrte, et on la place dans
la variable "pizza" (interface et
classe mre des pizzas).
Une fois on a la pizza, on prpare la sauce, le
nappage (tomate/crme fraiche) et le fromage ,
puis on la fait cuire, la coupe, et on la met dans
une boite.
Ajouter ClamPizza au menu
On na pas vendu beaucoup de GreekPizza dernirement
Suspendre GreekPizza du menu
Ce code est NON ferm
pour la modification!
[Link]();
[Link]();
[Link]();
[Link]();
return pizza;
Les concurrents ont ajout un nouveau type de pizza: (avec Calamars)
if ([Link]("cheese"){
pizza=new CheesePizza();
} else if ([Link]("greek"){
pizza=new GreekPizza();
} else if ([Link]("pepperoni"){
pizza=new PepperoniPizza();
}
}
151
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Autres types de pizza (3/37)
Pizzeria: Crer plusieurs types de pizza
On veut plus quun type de pizza.
152
Pizza orderPizza(String type){
Pizza pizza;
if ([Link]("cheese"){
pizza=new CheesePizza();
Partie variable: On modifie
} else if ([Link]("greek"){
le code autant que la
pizza=new GreekPizza();
slection de pizza change.
} else if ([Link]("pepperoni"){
pizza=new PepperoniPizza();
} else if ([Link]("clam"){
pizza=new ClamPizza();
}
[Link]();
[Link]();
Partie invariable: Gnralement, ces oprations
[Link]();
sont les mmes pour des annes et des annes.
[Link]();
return pizza;
}
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Encapsuler la cration (4/37)
PizzaStore :
Un Simple Factory (5/37)
Rgle 1 de lOO: Encapsuler ce qui varie
if ([Link]("cheese"){
pizza=new CheesePizza();
} else if ([Link]("pepperoni"){
pizza=new PepperoniPizza();
} else if ([Link]("clam"){
pizza=new ClamPizza();
}
public class SimplePizzaFactory {
public Pizza createPizza(String type){
Pizza pizza=null;
if ([Link]("cheese"){
pizza=new CheesePizza();
} else if ([Link]("pepperoni"){
pizza=new PepperoniPizza();
} else if ([Link]("clam"){
pizza=new ClamPizza();
}
Pizza orderPizza(String type){
Pizza pizza;
On place ce code dans un objet qui soccupera de la
cration des pizzas concrtes. Si un autre objet a besoin
dune pizza concrte, cest cet objet quil faut appeler.
[Link]();
[Link]();
[Link]();
[Link]();
return pizza;
Le seul rle de SimplePizzaFactory est de crer des pizzas pour ces
clients
Initialement, on dfinit la mthode
createPizza() dans le Factory. Cest la
mthode que tous les clients utilisent
pour instancier des nouveaux objets.
Cest le code quon a retirer de la
mthode orderPizza().
return pizza;
}
}
}
153
154
OnRiadh
attribue
le nom Factory
ce nouvel
objet
BEN HALIMA&Wajdi
LOUATI
[Design patterns]
PizzaStore :
Retravaillons la classe PizzaStore (6/37)
PizzaStore :
Le diagramme de classes (7/37)
Elle doit tre la seule partie de
notre application qui pointe vers les
classes des pizzas concrtes
Maintenant, PizzaStore utilise SimplePizzaFactory pour crer des pizzas
public class PizzaStore {
SimplePizzaFactory factory;
public PizzaStore(SimplePizzaFactory factory){
[Link]=factory;
}
public Pizza orderPizza(String type){
Pizza pizza;
PizzaStore rcupre la
rfrence du factory
travers le constructeur.
PizzaStore
orderPizza()
SimplePizzaFactory
La mthode orderPizza() utilise le
factory pour crer ses pizzas.
PizzaStore cre des
instances travers
SimplePizzaFactory
On dfinit Pizza comme
classe abstraite, avec quelque
implmentations qui peuvent
tre redfinies
Pizza
prepare()
bake()
cut()
box()
createPizza()
La mthode de cration
est souvent statique
pizza=[Link](type);
[Link]();
[Link]();
[Link]();
[Link]();
return pizza;
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
CheesePizza
PepperoniPizza
ClamPizza
}
Chaque produit implmente la classe abstraite Pizza
Noter quon a remplac loprateur new par une mthode concrte
Plus dinstanciation concrte ici
155
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Actuellement, Simple Factory nest pas un patron. Cest plutt un
"style" de programmation
156
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Franchise de PizzaStore (8/37)
Objectif: Franchiser PizzaStore: Crer plusieurs stores dans
plusieurs villes (Sfax, Tunis, etc.)
Besoin: Dvelopper une application qui gre la cration des
pizzas pour chaque store
PizzaStore :
Diffrent styles des PizzaStores (9/37)
Chaque store offre diffrent types de pizza
Conception: OO
Si on prpare les mmes pizzas
SfaxPizzaFactory sffactory = new SfaxPizzaFactory();
PizzaStore sfstore = new PizzaStore(sffactory);
[Link]("cheese");
Crer les mmes pizzas
travers TunisPizzaFactory
TunisPizzaFactory tnfactory = new TunisPizzaFactory();
PizzaStore tnstore = new PizzaStore(tnfactory);
[Link]("cheese");
Moins de fromage dans
les pizzas, etc.
Et si chaque PizzaStore prpare ses propres styles de pizza
Je prpare les pizzas depuis des
annes et je veux ajouter mes propres
touches damlioration des procdures de
mon PizzaStore
Des pizzas familles de
grande taille, beaucoup
de fromage, etc.
157
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Le framework de PizzaStore (10/37)
158
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Les styles de pizzas (11/37)
On donne la libert aux franchises de crer leurs propres styles
PizzaStore
createPizza()
orderPizza()
Dplacer la cration dans une la mthode createPizza() et garder la
mme mthode orderPizza() pour tous les stores
Chaque rgion ltend afin de spcifier son propre style
Crer des pizzas
avec les ingrdients
spcifiques Sfax
public abstract class PizzaStore {
public Pizza orderPizza(String type){
Pizza pizza;
CreatePizza() est une
mthode PizzaStore plutt
que dans le Factory
pizza = createPizza(type);
[Link]();
[Link]();
[Link]();
[Link]();
return pizza;
Tout ceci apparat le mme
On a transfr notre objet
Factory dans cette mthode
}
abstract Pizza createPizza(String type);
}
159
Crer des pizzas travers
SfaxPizzaFactory
Notre "mthode Factory" est
maintenant abstraite dans
Riadh PizzaStore
BEN HALIMA&Wajdi LOUATI [Design patterns]
SfaxStylePizzaStore
TunisStylePizzaStore
createPizza()
createPizza()
Pizza createPizza(String type) {
Pizza pizza=null;
if ([Link]("cheese"){
pizza=new SfaxStyleCheesePizza();
} else if ([Link]("pepperoni"){
pizza=new SfaxStylePepperoniPizza();
} else if ([Link]("clam"){
pizza=new SfaxStyleClamPizza();
}
return pizza;
}
160
Mthode abstraite, dfinir
dans les classes drives
Crer des pizzas
avec les ingrdients
spcifiques Tunis
Pizza createPizza(String type) {
Pizza pizza=null;
if ([Link]("cheese"){
pizza=new TunisStyleCheesePizza();
} else if ([Link]("pepperoni"){
pizza=new TunisStylePepperoniPizza();
} else if ([Link]("clam"){
pizza=new TunisStyleClamPizza();
}
return pizza;
}
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Un PizzaStore de Style Sfaxien (12/37)
PizzaStore :
Commander des pizzas (13/37)
Les bnfices dune franchise
Je voudrai une pizza
de grande taille avec beaucoup
de fromage du style
tunisien
On obtient des fonctionnalits des pizzas communes (prepare(), bake(), cut() et box())
Chaque rgion dfinit sa propre mthode createPizza() qui spcifie son style de pizza
public class SfaxStylePizzaStore extends PizzaStore {
Pizza createPizza(String item) {
On hrite la mthode
if ([Link]("cheese"){
orderPizza() de PizzaStore
return new SfaxStyleCheesePizza();
} else if ([Link]("pepperoni"){
On implmente createPizza()
return new SfaxStylePepperoniPizza();
puisquelle est abstraite:
} else if ([Link]("clam"){
Cest la "mthode Factory"
return new SfaxStyleClamPizza();
}
}
Crer des pizzas du style sfaxien!!
}
Rq: Toutes les responsabilits dinstanciation sont dplaces vers la mthode
createPizza() qui agit comme un factory
La mthode factory gre la cration des objets et leur encapsulation
PizzaStore tunisps =
new TunisStylePizzaStore();
Prendre des commandes
[Link]("cheese");
[Link]("cheese");
Cest une mthode de linstance tunisps (respectivement
sfaxps), dfinie dans la classe PizzaStore
162
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Implmenter (15/37)
PizzaStore :
Commander des pizzas (14/37)
[Link]("cheese");
PizzaStore sfaxps =
new SfaxStylePizzaStore();
Instance du store spcifique
Dcouplage du code du client dans la supre classe de la cration de lobjet dans les sousclasses
161
Je voudrai une pizza
de taille moyenne avec
peu de fromage et au thon
du style sfaxien
[Link]("cheese");
La mthode orderPizza() appelle createPizza()
Implmenter les classes:
[Link], [Link]
et [Link]
PizzaStore
createPizza()
orderPizza()
SfaxStylePizzaStore
createPizza()
Pizza pizza= createPizza("cheese");
On termine la prparation
[Link]();
[Link]();
[Link]();
[Link]();
De style tunisien
TunisStylePizzaStore
createPizza()
Implmenter les classes: [Link],
Les produits
Pizza
[Link],
[Link],
[Link],
[Link],
SfaxStyleCheesePizza TunisStyleCheesePizza
[Link],
[Link] SfaxStyleClamPizza
TunisStyleClamPizza
SfaxStylePepperoniPizza
163
Factory Method
Pizza pizza= createPizza("cheese");
La mthode createPizza() est implmente dans la classe drive
Elle retourne une pizza au
Elle retourne une pizza au
fromage style tunisien
fromage style sfaxien
[Link]();
[Link]();
[Link]();
[Link]();
Les crateurs
Riadh BEN HALIMA&Wajdi
LOUATI [Design patterns]
De style sfaxien
164
TunisStylePepperoniPizza
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Le patron Factory Method (16/37)
Dfinition:
Factory Method
Le patron factory method dfinit une interface de
cration des objets, et laisse les classes-drives dcider de
la classe de linstanciation. La mthode factory permet
une classe de dlguer linstanciation ces classes drives.
PizzaStore :
Le diagramme de classes du patron (17/37)
La classe mre de tous les produits
concrets. Elle reprsente aussi le type
gnrique qui rfrence vers les
instances des classes concrtes
Product
Le Creator est une classe qui contient
limplmentation de toutes les
mthodes qui manipulent le produits,
lexception de factoryMethod()
Creator
La mthode abstraite
facotoryMethod() que tous
les drivs de la classe
Creator implmentent
factoryMethod()
anOperation()
ConcretProduct
ConctretCreator
Le ConcretCreator
implmente la mthode
facotoryMethod(), qui
produit les produits
factoryMethod()
Le ConcretCreator est responsable de la cration de produits
concrets. Cest la classe qui connait le qui a cr chaque produit
165
166
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Un PizzaStore dpendant (18/37)
Hypothse: On na jamais entendu parler du factory
Compter le nombre dobjets de pizzas concrtes dont cette classe dpend
Refaire le compte si on ajoute des pizzas de style bizertin
public class DependentPizzaStore {
Pizza createPizza(String style, String type) {
Pizza pizza=null;
if ([Link]("Sfax")){
Grer toutes les pizzas de
if ([Link]("cheese"){
style sfaxien
pizza=new SfaxStyleCheesePizza();
} else if ([Link]("pepperoni"){
pizza=new SfaxStylePepperoniPizza();
} else if ([Link]("clam"){
pizza=new SfaxStyleClamPizza();
}
} else if ([Link]("Tunis")){
Grer toutes les pizzas de
if ([Link]("cheese"){
pizza=new TunisStyleCheesePizza();
style tunisois
} else if ([Link]("pepperoni"){
pizza=new TunisStylePepperoniPizza();
} else if ([Link]("clam"){
pizza=new TunisStyleClamPizza();
}
} else {[Link]("Erreur: type de pizza invalide");}
[Link]();
[Link]();
[Link]();
[Link]();
return pizza;
167 }
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
}
La dcision: choix
du produit concret
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
La dpendance entre les objets (19/37)
Cette version de PizzaStore dpend de tous les objets pizzas parce quelle les cre
directement
On dit que PizzaStore dpend des implmentations des pizzas parce que chaque
changement des implmentations concrtes des pizzas, affecte le PizzaStore
Si les implmentations des pizzas
changent, on doit modifier PizzaStore
Pour chaque nouveau type de pizza,
on ajoute une autre dpendance dans
la mthode create()
168
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Linversion de dpendance (20/37)
Rduire les dpendances aux classes concrtes dans notre code,
est une "bonne chose"
Le principe qui formalise cette notion sappelle "principe
dinversion de dpendance" :
Les classes de pizzas concrtes dpendent
aussi de labstraction Pizza, parce quelles
implmentent linterface Pizza
Rgle 5: Dpendre des abstractions. Ne jamais dpendre
de classes concrtes.
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Les ingrdients des pizzas (22/37)
Pizza est une classe
abstraite.. abstraction
PizzaStore dpend seulement de
Pizza, qui est une classe abstraite
Ce principe prtend que nos "haut-niveau" composants ne
doivent pas dpendre de nos "bas-niveau" composants; plutt, les
deux doivent dpendre des abstractions.
Un composant de haut-niveau (PizzaStore) est une classe dont le
comportement dpend des autres composants de basniveau(Pizza)
169
PizzaStore :
Appliquons ce principe (21/37)
Problme : quelques franchises nont pas utilis la
mme procdure de prparation, et ce en substituant
des ingrdients par dautres de basse qualit, afin
daugmenter leur marge.
! Il faut assurer la consistance des ingrdients
Solution : crer un factory qui produit les ingrdients,
et les transporter aux franchises
Le seul problme avec ce plan : Ce qui est sauce rouge
Sfax, nest pas sauce rouge Tunis
171
Le "Factory Method"
est la technique la plus
puissante dadhrence
au principe dinversion
de dpendance, mais
pas la seule...
170
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Les menus des pizzas (23/37)
Sfax
Pizza Menu
Cheese Pizza
Sauce marinara, Parmesan,
Emmental
Clam Pizza
Sauce marinara, Parmesan,
Clovis, Olive verte
Pepperoni Pizza
Sauce marinara, Parmesan,
Aubergine, Poivron, Olive verte
Nous avons les mmes
familles de produits, mais
diffrente implmentations
selon la rgion
Tunis
Pizza Menu
Cheese Pizza
Sauce tomate prune, Mozzarella,
Roquefort
Clam Pizza
Sauce tomate prune, Mozzarella,
Palourde, Olive noire
Pepperoni Pizza
Sauce tomate prune, Mozzarella,
pinard, Poivre, Olive noire
Il y a un ensemble dingrdients transporter Sfax, et un
autre ensemble transporter Tunis
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
172
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Les familles des ingrdients (24/37)
Chaque famille correspond un
type de sauce, un type de
fromage, un type de lgume, et un
type dolive (et dautres types)
PizzaStore :
Les factories des ingrdients (25/37)
Tunis
PlumTomatoSauce
Spinach
Mozzarella
Pour chaque ingrdient, on
public interface PizzaIngredientFactory {
cre une create() mthode
public Dough createDough();
dans notre interface
public Sauce createSauce();
public Cheeze createCheese();
public veggies[] createVeggies();
public Clam createClam();
Beaucoup de nouvelles
}
classes, une par ingredient
BlackOlive
Sfax
MarinaraSauce
Eggplant
173
Parmesan
GreenOlive
Toutes les PizzaStores utilisent
les mmes composants, mais
chaque rgion possde une
implmentation spcifique de ces
composants
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Les factories de Sfax (26/37)
public class SfaxPizzaIngredientFactory implements PizzaIngredientFactory
{
public Dough createDough(){
return new ThinDough();
Pour chaque famille dingrdient, on
}
cre la version sfaxienne
public Sauce createSauce(){
return new MarinaraSauce();
}
public Cheese createCheese(){
return new Parmesan();
}
public Veggies[] createVeggies(){
Veggies veggies[]={new Garlic(), new Onion(), new Eggplant()};
return veggies;
}
public Clam createClam(){
return new Clovis();
}
Palourde() pour le
}
cas de tunis
175
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Le factory est le responsable de la cration de la pte, la sauce,
le fromage, etc.
A faire :
Construire un facotry pour chaque rgion: une sous-classe de
PizzaIngredientFactory qui implmente chaque create() mthode
Implmenter un ensemble de classes dingrdients, utiliser par les
factories tels que: OliveVerte, Mozzarella, SauseMarinara, etc.
Lier ceci avec notre ancien code de PizzaStore, tout en travaillant
nos factories dingrdients
174
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Retravaillons la classe Pizza (27/37)
public abstract class Pizza {
Les ingrdients dune paizza
String name;
(liste non-exhaustive)
Dough dough;
Sauce sauce;
La collecte des ingrdients se fait dans cette
Cheese cheese;
mthode ( travers un factory dingrdients)
Veggies veggies[];
qui sera dfinie par les classes drives
Clam clam;
abstract void prepare();
void bake(){
[Link]("Cuire durant 25mn 350");}
void cut(){
[Link]("Couper en morceaux la diagonale");}
void box(){
[Link]("Placer la pizza dans un boitier officiel");}
void setName(String s){
name=s;}
Les autres mthodes sont les
String getName(){
mmes ( lexception de prepare())
return name;}
}
176
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Retravaillons les classes des Pizzas (28/37)
PizzaStore :
Retravaillons les classes des Pizzas (29/37)
Pour faire la pizza, on besoin dun
factory. Chaque classe Pizza prend le
factory travers son constructeur
public class CheesePizza extends Pizza {
PizzaIngredientFactory ingredientfactory;
CheesePizza(PizzaIngredientFactory ingredientfactory){
[Link] = ingredientfactory;
}
void prepare(){
[Link]("Prparons " +name);
dough = [Link]();
sauce = [Link]();
cheese = [Link]();
}
}
Chaque fois que la mthode prepare()
a besoin dingrdient, elle appelle le
factory pour le produire
177
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Retravaillons les PizzaStores (30/37)
Un factory pour chaque type de Pizza
public class ClamPizza extends Pizza {
PizzaIngredientFactory ingredientfactory;
ClamPizza(PizzaIngredientFactory ingredientfactory){
[Link] = ingredientfactory;
}
void prepare(){
[Link]("Prparons " +name);
dough = [Link]();
sauce = [Link]();
cheese = [Link]();
clam= [Link]();
}
Pour faire une ClamPizza, la mthode
prpare les ingrdients
correspondants de son factory local.
}
Si cest le factory de sfax, on
va prparer des clovis
178
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Factories (31/37)
Dfinit linterface
Le store de Sfax est compos dun
factory sfaxien dingrdients/
public class SfaxPizzaStore extends PizzaStore {
Pizza createPizza(String item) {
Pizza pizza = null;
PizzaIngredientFactory ingredientfactory=
new SfaxPizzaIngredientFactory();
On passe chaque pizza le factory
if ([Link]("cheese"){
cens crer ses ingrdients
pizza = new CheesePizza(ingredientfactory);
[Link]("Sfax Style Cheese Pizza");
} else if ([Link]("pepperoni"){
pizza = new PepperoniPizza(ingredientfactory);
[Link]("Sfax Style Pepperoni Pizza");
} else if ([Link]("clam"){
pizza = new ClamPizza(ingredientfactory);
[Link]("Sfax Style Clam Pizza");
}
return pizza;
}
}
179
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Offre les
implmentations
des ingrdients
Abstract Ingredient Factory
Sfax
En passant (au constructeur) une varit
de factories, on obtient une varit
dimplmentations, tout en gardant le
mme code du client
180
Tunis
De labstract factory, on drive
plusieurs concrets factories qui
produisent les mmes produits, mais avec
diffrentes implmentations
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Commander des pizzas (33/37)
PizzaStore :
Commander des pizzas (32/37)
Je voudrai une pizza
de grande taille avec beaucoup
de fromage du style
tunisien
Je voudrai une pizza
de taille moyenne avec
peu de fromage et au thon
du style sfaxien
[Link]("cheese");
La mthode orderPizza() appelle initialement createPizza()
Pizza pizza= createPizza("cheese");
PizzaStore tunisps =
new TunisPizzaStore();
[Link]("cheese");
PizzaStore sfaxps =
new SfaxPizzaStore();
Pizza pizza= createPizza("cheese");
La mthode createPizza() implique le factory dingrdients
Pizza pizza= new
Pizza pizza= new
CheesePizza(tunisIngeredientFactory); CheesePizza(sfaxIngeredientFactory);
Instance du store spcifique
Chaque instance de pizza est associe un factory dingrdients
La mthode prepare() est appele et chaque factory est appel pour produire les
ingrdients de la rgion
Prendre des commandes
[Link]("cheese");
[Link]("cheese");
181
182
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
void prepare(){
dough = [Link]();
// Pte mince
sauce = [Link]();
// Sauce marinara
cheese = [Link]();
// Parmesan, Emmental
}
Elle prpare une pizza au
fromage avec les ingrdients
du style tunisien
CheesePizza la tunisoise
CheesePizza la sfaxienne
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Le patron Abstract Factory (35/37)
PizzaStore :
Commander des pizzas (34/37)
void prepare(){
dough = [Link]();
// Pte coustillante
sauce = [Link]();
// Sauce tomate prune
cheese = [Link]();
// Mozzarella, Roquefort
}
void prepare(){
void prepare(){
Cest une mthode de linstance tunisps (respectivement
sfaxps), dfinie dans la classe PizzaStore
Dfinition:
Abstract Factory
Le patron abstract factory offre une interface de
cration de familles dobjets dpendants (en relation), sans
spcifier leurs classes concrtes.
Elle prpare une pizza au
fromage avec les ingrdients
du style sfaxien
On termine la cration
[Link]();
[Link]();
[Link]();
183
De style tunisien
[Link]();
[Link]();
[Link]();
Riadh BEN HALIMA&Wajdi
LOUATI [Design patterns]
De style sfaxien
184
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
PizzaStore :
Le diagramme de classes du patron (36/37)
PizzaStore :
La conception finale (37/37)
Le client est compos au moment de
lexcution par un factory concret
Labstract factory dfinit un
ensemble de mthodes pour la
production des produits
Client
Une famille de produits
<<interface>>
AbstractFactory
createProductA()
createProductB()
SfaxPizzaStore
<<interface>>
PizzaIngredientFactory
createSauce()
createCheese()
createClam()
//etc.
ProductA1
createProductA()
createProductB()
createProductA()
createProductB()
ProductB2
ProductB1
Les factories concrets implmentent les
diffrences familles de produits
185
TunisPizzaIngred SfaxPizzaIngredi
ientFActory
entFactory
createSauce()
createSauce()
createCheese()
createCheese()
createClam()
createClam()
La tche des factories est de produire les
ingrdients spcifiques chaque rgion
186
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Rcapitulatif (1/2)
Palourde
<<interface>>
Sauce
PlumTomatoSauce
<<interface>>
Cheese
Parmesan
Mozzarella
Chaque factory produit diffrent implmentation
Riadh BEN
HALIMA&Wajdi
de chaque
famille
de produits LOUATI [Design patterns]
Rcapitulatif (2/2)
Bases de lOO: Abstraction, Encapsulation, Polymorphisme & Hritage
Principes de lOO
Encapsuler ce qui varie
Favoriser la composition sur lhritage
Programmer avec des interfaces et non des implmentations
Opter pour une conception faiblement couple
Les classes doivent tre ouvertes pour les extensions et fermes pour les
modifications
Dpendre des abstractions. Ne jamais dpendre de classes concrtes
Patron de lOO
Strategy: dfinit une famille dalgorithmes interchangeables
Observer: dfinit une dpendance1--plusieurs entre objets.
Decorator: attache des responsabilits additionnelles un objet dynamiquement.
Factory Method: dfinit une interface de cration des objets, et laisse les
classes-drives dcider de la classe de linstanciation.
Abstract Factory: offre une interface de cration de familles dobjets
dpendants, sans spcifier leurs classes concrtes
187
Clovis
MarinaraSauce
<<interface>>
AbstractProductB
ConcretFactory1 ConcretFactory2
<<interface>>
Clam
Labstract factory dfinit un
lensemble des produits quon a
besoin pour faire une pizza
<<interface>>
AbstractProductA
ProductA2
Les clients de labstract factory
sont les stores de Sfax et de Tunis
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]
Tous les factories encapsule la cration des objets
Malgr quil nest un vrai patron, le "Simpe Factory" est une manire simple
de dcouplage de clients des concrtes classes
Factory Method repose sur lhritage: La cration dobjet est dlgue aux
sous-classes qui implmentent la mthode factory de cration dobjets
Abstract Factory repose sur la composition dobjets: La cration dobjet est
implmente dans une mthode expose dans linterface du factory
Tous les patrons factories soutiennent le faible couplage entre notre
application et les classes concrtes.
Lintension de Factory Method est de permettre une classe de reporter
linstanciation ses sous-classes.
Lintension dAbstract Factory est de crer une famille dobjets en relation
sans dpendre de leurs classes concrtes
Linversion de dpendance nous guide afin dviter les dpendances des
classes concrtes, et sefforcer pour les abstractions
Factories sont des techniques puissantes de codages des abstractions et non
des classes concrtes
188
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]