Vous êtes sur la page 1sur 47

Plan

Les patrons de conception


(Design patterns)

Riadh BEN HALIMA

Wajdi LOUATI

riadh.benhalima@enis.rnu.tn

wajdi.louati@gmail.com

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(){


qbehavior.quack();
}
//..
}
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(){
System.out.println("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 (Duck.java)


Le comportements: FlyBehavior.java, FlyWithWings.java et

Le comportement : QuackBehavior.java, Quack.java, Squeak.java et


MuteQuack.java

Les classes MallardDuck.java et WoodenDuck.java

Tester toutes les mthodes des canards crs dans un main:


MallardDuckSim.java

27

Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]

Changement dynamique de comportement

FlyNoWay.java,

Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]

Ajouter les mthodes: setFlyBehavior() et setQuackBehavior()


Dvelopper le canard RedHeadDuck (RedHeadDuck.java)
Implanter le nouveau comportement "vole-force-fuse"
FlyRocketPowered (FlyRocketPowered.java)
Tester le nouveau canard dans un main RedHeadSim.java
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) {
this.arme=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 (CurrentConditionsDisplay.java)


statistiques mtorologique (StatisticsDisplay.java)
prvisions mto (ForecastDisplay.java)

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.

java.util.Observable : Subject du patron (Attention! Il sagit dune classe)


java.util.Observer : 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{Thread.sleep(1000);}
catch(InterruptedException e) {System.out.print("erreur");}
c.tick((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()

Beverage.java, Coffee.java, CoffeeWithMilk.java,


CoffeeWithMilkWithWhip.java, Tea.java, TeaWithMint.java,
TeaWithMintWithPine.java, 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 java.io doit donner plus de


sens, puisquil se base largement sur ce patron.
FileInputStream est un composant
dcor. Le package java.io 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 java.io


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
System.out.println("La voiture est une "+v1.getDescription());
//affiche: La voiture est une P404 avec ABS
System.out.println("Son prix est:"+ v1.cost());
//affiche: Son prix est 10800
System.out.println("La voiture est une "+v2.getDescription());
//affiche: La voiture est une P407 avec VitreElectrique, AirBag
System.out.println("Son prix est:"+ v2.cost());
//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(){
System.out.println("Quack");}
public void fly(){
System.out.println("Fly");}
}

class TurkeyAdapter implements Duck{


Turkey turkey;
TurkeyAdapter(Turkey turkey){
this.turkey=turkey;}
Une rfrence vers lobjet adapter
public void quack(){
turkey.gobble();
}
public void fly(){
for(int i=0;i<5;i++)
turkey.fly();
}
}

Le dinde ne cancane pas, mais glougloute


Le dinde peut voler (courte distance)

class WildTurkey implements Turkey{


public void gobble(){
System.out.println("Gobble");}
public void fly(){
System.out.println("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)
{
duck.quack();
duck.fly();
}
}

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 : MonObjet.getInstance()

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= Singleton.getInstance();
}
}
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
Singleton.getInstance(). 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(Singleton.class) {
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(){
receiver.action()
}
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){
this.light = light;
}
public void execute(){
light.on();
}
}

ConctretCommand

action()

execute()
undo()

Le Receiver connait comment raliser le


travail demand afin de satisfaire la requte.

public void execute(){


receiver.action();
}

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;
}

remote.setCommand(lightOn); //passer la commande linvoker


remote.buttonWasPressed(); //simuler lappui sur le bouton

public void buttonWasPressed(){


slot.execute();
}

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){
this.garageDoor = garageDoor;
}
public void execute(){
garageDoor.up();
garageDoor.lightOn();
}
}
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);
remote.setCommand(lightOn); //encapsuler la commande
remote.buttonWasPressed(); //allumer la lumire
remote.setCommand(garageOpen); //encapsuler la commande
remote.buttonWasPressed(); //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()
light.on();
public void execute(){
}
light.off();
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);
remoteControl.setCommand(0, livingRoomLightOnCommand,livingRoomLightOffCommand);
remoteControl.onButtonWasPressed(0);
remoteControl.offButtonWasPressed(0);
Stereo stereo = new Stereo();
StereoOnWithCDCommand stereoOnWithCDCommand = new
StereoOnWithCDCommand(stereo);
StereoOffCommand stereoOffCommand = new StereoOffCommand(stereo);
remoteControl.setCommand(1,stereoOnWithCDCommand,stereoOffCommand);
remoteControl.onButtonWasPressed(1);
remoteControl.offButtonWasPressed(1);
System.out.println(remoteControl.toString());
}
}
Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]

Programmer les classes suivantes:

Light.java, Stereo.java
LightOnCommand,.java LightOffCommand.java,
StereoOnWithCDCommand.java, StereoOffCommand.java

class LightOnCommand
implements Command {
Light light;
public LightOnCommand(Light
light){
this.light = light;
}
public void execute(){
light.on();
}
}

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){
this.stereo = stereo;
}
public void execute(){
stereo.on();
stereo.setCD();
stereo.setVolume(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()
this.light = light;
}
public void execute(){
light.on();
}
public void undo(){
Opration excuter en cas
light.off();
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
undoCommand.undo();
}
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){
this.commands = commands;
Un boucle pour excuter
}
toutes les commandes de la
public void execute(){
macro-commande
for (int i=0;i<commands.length;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[]){
//
remoteControl.onButtonWasPressed(0);
remoteControl.undoButtonWasPressed();
//
remoteControl.onButtonWasPressed(1);
remoteControl.offButtonWasPressed(1);
System.out.println(remoteControl.toString());
}
}

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


remoteControl.setCommand(2, onMacro, offMacro);
Affecter les macro-commandes
au bouton du slot n2

Excuter la macro-commande
System.out.println("Macro On");
remoteControl.onButtonWasPushed(2);
System.out.println("Macro Off");
remoteControl.offButtonWasPushed(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();
control.setCommand(0, plus);
control.setCommand(1, sous);
control.setCommand(2, mult);
control.MultiButtonPressed(2, 5, 15);
control.SoustButtonPressed(1, 17, 10);
control.PlusButtonPressed(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!

pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
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!

pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;

Les concurrents ont ajout un nouveau type de pizza: (avec Calamars)

if (type.equals("cheese"){
pizza=new CheesePizza();
} else if (type.equals("greek"){
pizza=new GreekPizza();
} else if (type.equals("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 (type.equals("cheese"){
pizza=new CheesePizza();
Partie variable: On modifie
} else if (type.equals("greek"){
le code autant que la
pizza=new GreekPizza();
slection de pizza change.
} else if (type.equals("pepperoni"){
pizza=new PepperoniPizza();
} else if (type.equals("clam"){
pizza=new ClamPizza();
}
pizza.prepare();
pizza.bake();
Partie invariable: Gnralement, ces oprations
pizza.cut();
sont les mmes pour des annes et des annes.
pizza.box();
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 (type.equals("cheese"){
pizza=new CheesePizza();
} else if (type.equals("pepperoni"){
pizza=new PepperoniPizza();
} else if (type.equals("clam"){
pizza=new ClamPizza();
}

public class SimplePizzaFactory {


public Pizza createPizza(String type){
Pizza pizza=null;
if (type.equals("cheese"){
pizza=new CheesePizza();
} else if (type.equals("pepperoni"){
pizza=new PepperoniPizza();
} else if (type.equals("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.
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
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){
this.factory=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=factory.createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
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);
sfstore.orderPizza("cheese");
Crer les mmes pizzas
travers TunisPizzaFactory
TunisPizzaFactory tnfactory = new TunisPizzaFactory();
PizzaStore tnstore = new PizzaStore(tnfactory);
tnstore.orderPizza("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);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
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 (type.equals("cheese"){
pizza=new SfaxStyleCheesePizza();
} else if (type.equals("pepperoni"){
pizza=new SfaxStylePepperoniPizza();
} else if (type.equals("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 (type.equals("cheese"){
pizza=new TunisStyleCheesePizza();
} else if (type.equals("pepperoni"){
pizza=new TunisStylePepperoniPizza();
} else if (type.equals("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 (item.equals("cheese"){
orderPizza() de PizzaStore
return new SfaxStyleCheesePizza();
} else if (item.equals("pepperoni"){
On implmente createPizza()
return new SfaxStylePepperoniPizza();
puisquelle est abstraite:
} else if (item.equals("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


tunisps.orderPizza("cheese");

sfaxps.orderPizza("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)
tunisps.orderPizza("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

sfaxps.orderPizza("cheese");

La mthode orderPizza() appelle createPizza()

Implmenter les classes:


PizzaStore.java, SfaxPizzaStore.java
et TunisPizzaStore.java

PizzaStore
createPizza()
orderPizza()

SfaxStylePizzaStore
createPizza()
Pizza pizza= createPizza("cheese");

On termine la prparation
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();

De style tunisien

TunisStylePizzaStore
createPizza()

Implmenter les classes: Pizza.java,


Les produits
Pizza
SfaxStyleCheesePizza.java,
SfaxStyleClamPizza.java,
SfaxStylePepperoniPizza.java,
TunisStyleCheesePizza.java,
SfaxStyleCheesePizza TunisStyleCheesePizza
TunisStyleClamPizza.java,
TunisStylePepperoniPizza.java 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

pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();

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 (style.equals("Sfax")){
Grer toutes les pizzas de
if (type.equals("cheese"){
style sfaxien
pizza=new SfaxStyleCheesePizza();
} else if (type.equals("pepperoni"){
pizza=new SfaxStylePepperoniPizza();
} else if (type.equals("clam"){
pizza=new SfaxStyleClamPizza();
}
} else if (style.equals("Tunis")){
Grer toutes les pizzas de
if (type.equals("cheese"){
pizza=new TunisStyleCheesePizza();
style tunisois
} else if (type.equals("pepperoni"){
pizza=new TunisStylePepperoniPizza();
} else if (type.equals("clam"){
pizza=new TunisStyleClamPizza();
}
} else {System.out.println("Erreur: type de pizza invalide");}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
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(){
System.out.println("Cuire durant 25mn 350");}
void cut(){
System.out.println("Couper en morceaux la diagonale");}
void box(){
System.out.println("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){
this.ingredientfactory = ingredientfactory;
}
void prepare(){
System.out.println("Prparons " +name);
dough = ingredientfactory.createDough();
sauce = ingredientfactory.createSauce();
cheese = ingredientfactory.createCheese();
}
}

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){
this.ingredientfactory = ingredientfactory;
}
void prepare(){
System.out.println("Prparons " +name);
dough = ingredientfactory.createDough();
sauce = ingredientfactory.createSauce();
cheese = ingredientfactory.createCheese();
clam= ingredientfactory.createClam();
}
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 (item.equals("cheese"){
cens crer ses ingrdients
pizza = new CheesePizza(ingredientfactory);
pizza.setName("Sfax Style Cheese Pizza");
} else if (item.equals("pepperoni"){
pizza = new PepperoniPizza(ingredientfactory);
pizza.setName("Sfax Style Pepperoni Pizza");
} else if (item.equals("clam"){
pizza = new ClamPizza(ingredientfactory);
pizza.setName("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

tunisps.orderPizza("cheese");

La mthode orderPizza() appelle initialement createPizza()


Pizza pizza= createPizza("cheese");

PizzaStore tunisps =
new TunisPizzaStore();

sfaxps.orderPizza("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


tunisps.orderPizza("cheese");

sfaxps.orderPizza("cheese");

181

182

Riadh BEN HALIMA&Wajdi LOUATI [Design patterns]

void prepare(){
dough = factory.createDough();
// Pte mince
sauce = factory.createSauce();
// Sauce marinara
cheese = factory.createCheese();
// 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 = factory.createDough();
// Pte coustillante
sauce = factory.createSauce();
// Sauce tomate prune
cheese = factory.createCheese();
// 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

pizza.bake();
pizza.cut();
pizza.box();

183

De style tunisien

pizza.bake();
pizza.cut();
pizza.box();

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]

Vous aimerez peut-être aussi