Vous êtes sur la page 1sur 128

Patrons de conception

(Design Patterns)

Xavier Crégut
<Prenom.Nom@enseeiht.fr>

Département Télécommunications & Réseaux


ENSEEIHT

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 1 / 128


Sommaire

1 Pourquoi les patrons ?

2 Patrons fondamentaux

3 Patrons créateurs

4 Patrons structurels

5 Patrons comportementaux

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 2 / 128


Sommaire

1 Pourquoi les patrons ?


Historique
2 Patrons fondamentaux Motivation
Définition
3 Patrons créateurs Rubriques de la description
Classification
4 Patrons structurels Utilisation

5 Patrons comportementaux

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 3 / 128


Pourquoi les patrons ?

Historique
Motivation
Définition
Rubriques de la description
Classification
Utilisation

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 4 / 128


Historique
Notion de « patron » d’abord apparue en architecture :
I Christopher Alexander : « The Timeless Way of Constructing », 1979
I Définition de « patrons » pour :
F l’architecture des bâtiments
F la conception des villes et de leur environnement
I Christopher Alexander :
« Chaque modèle [patron] décrit un problème qui se manifeste
constamment dans notre environnement, et donc décrit le cœur de la
solution de ce problème, d’une façon telle que l’on peut réutiliser cette
solution des millions de fois, sans jamais le faire deux fois de la
même manière. »
Idée : appliquer la notion de patron à du logiciel : « design patterns »
I premiers patrons à partir de 1987 (partie de la thèse de Erich Gamma)
I puis Richard Helm, John Vlissides et Ralph Johnson (« Gang of Four, GoF »)
I 1er catalogue en 1993 : Elements of Reusable Object-Oriented Software
Vocabulaire :
I design patterns I patrons de conception
I modèles de conception I micro-architectures

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 5 / 128


Pourquoi les patrons ?

Historique
Motivation
Définition
Rubriques de la description
Classification
Utilisation

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 6 / 128


Intérêt des patrons de conception

Pourquoi définir des patrons de conception


Construire des systèmes plus extensibles, plus robustes au changement
Capitaliser l’expérience collective des informaticiens
Réutiliser les solutions qui ont fait leur preuve
Identifier les avantages/inconvénients/limites de ces solutions
Savoir quand les appliquer
Complémentaire avec les API
une API propose des solutions directement utilisables
un patron explique comment structurer son application, une API
Patron de conception dans le cycle de développement
intervient en conception détaillée
reste indépendant du langage d’implantation

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 7 / 128


Pourquoi les patrons ?

Historique
Motivation
Définition
Rubriques de la description
Classification
Utilisation

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 8 / 128


Qu’est ce qu’un patron de conception ?
Définition : Un patron de conception (design pattern) décrit une
structure commune et répétitive de composants en interaction (la
solution) qui résout un problème de conception dans un contexte
particulier.
Quatre éléments essentiels
I nom : un ou deux mots pour décrire le problème de conception
considérée, ses solutions et leurs conséquences.
I problème : situation où le problème s’applique
I solution : éléments de la conception, leurs relations et collaborations.
F la solution n’est pas forcément précise : idée d’architecture.
F plusieurs variantes peuvent être possibles.
I conséquences : effets résultants et compromis induits
F Les conséquences peuvent être positives ou négatives (arbitrage).

Un bon patron de conception :


I résout un problème
I correspond à une solution éprouvée
I favorise la réutilisabilité, l’extensibilité, etc.
I inclut une composante subjective : utilité, esthétique, etc.

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 9 / 128


Pourquoi les patrons ?

Historique
Motivation
Définition
Rubriques de la description
Classification
Utilisation

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 10 / 128


Description d’un patron de conception
Rubriques utilisées

Nom Collaborations
Intention Conséquences
Alias
Implantation
Motivation
Exemples de code
Indications d’utilisation
Structure Utilisations remarquables
Constituants Patrons apparentés

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 11 / 128


Description d’un patron de conception
Identification et compréhension du patron

Nom : nom de référence du patron


I étend le vocabulaire du concepteur
Intention : courte description de :
I ce que fait le patron de conception ;
I sa raison d’être ou son but ;
I cas ou problème particulier de conception concerné.
Alias : Autres noms connus pour le patron
Motivation :
I scénario qui illustre un cas de conception
I montre l’architecture en classes et objets de la solution
I aide à comprendre les descriptions plus abstraites du modèle
Indications d’utilisation :
I Quels sont les cas qui justifient l’utilisation du patron ?
I Quelles situations de conception peuvent tirer avantage du patron ?
I Comment reconnaître ces situations ?

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 12 / 128


Description d’un patron de conception
Description de la solution proposée par le patron

Structure : description de la solution sous forme de :


I un diagramme de classe pour l’architecture ;
I des diagrammes d’interaction pour la dynamique.
Constituants : classes/objets de la solution avec leurs responsabilités
Collaborations entre les constituants pour assumer leurs responsabilités
Conséquences :
I compromis induits par l’utilisation du patron
I impacts sur l’architecture de conception
I gains en terme de diminution du couplage dans la solution
Implantation : Solutions types, techniques, pièges et astuces.
Exemples de code : extraits de code illustrant la mise en œuvre du
patron
Utilisations remarquables : exemples issus de systèmes existants
Patrons apparentés :
I patrons similaires et différences essentielles
I utilisation conjointe avec d’autres patrons
Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 13 / 128
Pourquoi les patrons ?

Historique
Motivation
Définition
Rubriques de la description
Classification
Utilisation

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 14 / 128


Classification des patrons de conception

Fondamental Créateur Structurel Comportement


Fabrique Adaptateur Interprète
Délégation Fabrique abstraite Adaptateur Patron de méthode
Interface Monteur Pont Chaîne de responsabilités
Classe abstraite Prototype Composite Commande
Immuable Singleton Décorateur Itérateur
Interface de marquage Façade Médiateur
Poids mouche Mémento
Procuration Observateur
État
Stratégie
Visiteur

fondamental : application directe des concepts objets ;-)


créateur : processus de création d’objets
structurel : architecture statique du système
comportemental : interactions entre objets et répartition des responsabilités

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 15 / 128


Pourquoi les patrons ?

Historique
Motivation
Définition
Rubriques de la description
Classification
Utilisation

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 16 / 128


Choix d’un patron de conception

Est-il une solution au problème ?


Quels sont ses buts ?
Quelles sont les relations avec les autres patrons de conception ?
Est-ce que d’autres patrons jouent le même rôle ?

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 17 / 128


Mise en œuvre d’un patron de conception

Lire complètement la description, en particulier les sections indications


d’utilisation et conséquences.
Étudier en détail les sections Structure, Constituants et Collaborations
Regarder la section Exemple de code
Choisir des noms de constituants ayant un sens dans le contexte
d’utilisation !

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 18 / 128


Ce qu’il ne faut pas attendre des patrons de
conception

Une solution universelle prête à l’emploi


Une bibliothèque de classes réutilisables
L’automatisation totale de l’instanciation d’un patron de conception
La disparition du facteur humain

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 19 / 128


Sommaire

1 Pourquoi les patrons ?


Délégation
2 Patrons fondamentaux Interface
Classe abstraite
3 Patrons créateurs Interface et Classe abstraite
Immuable
4 Patrons structurels Interface de marquage

5 Patrons comportementaux

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 20 / 128


Patrons fondamentaux

Remarque : Les patrons fondamentaux découlent souvent


directement des concepts présents dans les langages objets.
=⇒ Suivant les auteurs, ils sont souvent considérés comme implicites
Intérêt :
I Donnent un autre éclairage aux concepts objet
I Sont utilisés par les autres patrons

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 21 / 128


Patrons fondamentaux

Délégation
Interface
Classe abstraite
Interface et Classe abstraite
Immuable
Interface de marquage

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 22 / 128


Délégation

Contexte : Parfois, utiliser l’héritage conduit à une mauvaise conception.


La délégation est alors un mécanisme plus général (même si plus lourd).
Cas où ne pas utiliser l’héritage (mais la délégation) :
I Une classe métier veut réutiliser une classe « utilitaire ».
F Évolutions de l’« utilitaire » compatibles avec la classe « métier » ?
I Une classe veut cacher des éléments de la superclasse (Anti-patron !).
F C’est impossible à faire (si héritage implique sous-typage, ex. Java) !
Exemple : Pile ne doit pas hériter de ArrayList.
I Les sous-classes modélisent des rôles différents de la superclasse.
Exemple : Modéliser un joueur de foot.
Spécialiser Joueur en Gardien, Stoppeur, Attaquant... ou définir une
délégation sur Poste qui est spécialisée en Gardien, Stoppeur, Attaquant...
Un joueur peut changer de poste, voire occuper plusieurs postes.
Remarque : L’héritage correspond à « est une sorte de » mais n’est pas
adapté pour représenter « est un rôle joué par » car, sinon, le rôle ne peut pas
changer pendant la durée de vie de l’objet.

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 23 / 128


Patrons fondamentaux

Délégation
Interface
Classe abstraite
Interface et Classe abstraite
Immuable
Interface de marquage

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 24 / 128


Interface

Intention : On souhaite qu’un client reste indépendant de la classe


qui fournit effectivement le service.
C’est justement l’objectif des interfaces ! (patron fondamental)
Exemple : Un client veut accéder à un fournisseur JDBC pour accéder à
une base de données. Le fournisseur effectif dépendra de la BD
considérée. Le code client n’a pas à le connaître, seulement les
interfaces qui définissent les services JDBC.
Intérêt : Le fournisseur de service peut changer sans impact sur le
code client.

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 25 / 128


Patrons fondamentaux

Délégation
Interface
Classe abstraite
Interface et Classe abstraite
Immuable
Interface de marquage

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 26 / 128


Classe abstraite

Intention :
I Garantir que la logique commune à plusieurs classes est implantée de
manière cohérente pour chaque classe
I Éviter le code redondant (et les efforts de maintenance associés)
I Faciliter l’écriture de nouvelles classes implantant la même logique
Solution :
I Utiliser une classe abstraite pour factoriser le code commun implantant la
logique
I Les méthodes peuvent éventuellement être définies comme final
Exemple : La classe abstraite java.util.AbstractCollection définit
toutes les opérations de Collection sauf size et iterator.
I Collection concrète non modifiable : définir seulement size et iterator
I Collection concrète modifiable : définir aussi add (et remove sur l’iterator).
Exemple 2 : La classe TestCase de JUnit (cf Patron de méthode, T. 109)

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 27 / 128


Patrons fondamentaux

Délégation
Interface
Classe abstraite
Interface et Classe abstraite
Immuable
Interface de marquage

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 28 / 128


Interface et classe abstraite

Idée :
Pourquoi choisir entre Interface et Classe abstraite ?
Faire les deux !
Intérêts :
on cumule les avantages des deux patrons
le client (surtout en Java) est libre de choisir entre :
I réaliser l’interface (et dupliquer le code mais hériter d’une autre classe)
I hériter de la classe abstraite (récupérer le code) mais sans pouvoir hériter
d’une autre classe
Exemple : L’API des collections en Java :
Collection et AbstractCollection,
List et AbstractList, etc.

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 29 / 128


Patrons fondamentaux

Délégation
Interface
Classe abstraite
Interface et Classe abstraite
Immuable
Interface de marquage

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 30 / 128


Immuable

Intention :
I Augmenter la robustesse des objets partageant les mêmes objets
I Diminuer le coût de la gestion du parallélisme.
Intérêts :
I facilite la gestion des objets partagés (personne ne peut les modifier !)
I permet de réaliser une composition sans avoir à faire de copie des objets
I pas de besoin de synchonisation (lecture seule)
I MAIS toute « modification » nécessite la création d’un nouvel objet
Exemple :
I String (immuable) par opposition à StringBuffer (modifiable).

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 31 / 128


Patrons fondamentaux

Délégation
Interface
Classe abstraite
Interface et Classe abstraite
Immuable
Interface de marquage

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 32 / 128


Interface de marquage

Intention : Définir une propriété sémantique booléenne sur une classe


Solution : Hériter d’une interface de marquage (interface vide).
Exemples :
I Cloneable indique que les objets d’une classe peuvent être clonés.
I Serializable indique qu’un objet peut être sérialisé1
Forces :
I Tester une propriété d’un objet/classe sans connaître la classe réelle
1 Object copie = null;
2 if (o instanceof Cloneable) {
3 copie = o.clone();
4 } else {
5 throw new CloneNotSupportedException();
6 }

I MAIS La propriété ne peut jamais être supprimée/désactivée


(obligatoirement héritée par les sous-classes)

1
sérialiser : encoder l’information en mémoire sous forme d’octets ou autres pour la
sauvegarder (persistance), la transporter à travers un réseau, etc.
Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 33 / 128
Sommaire

1 Pourquoi les patrons ?

Monteur
2 Patrons fondamentaux
Fabrique
Fabrique abstraite
3 Patrons créateurs
Prototype
Singleton
4 Patrons structurels

5 Patrons comportementaux

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 34 / 128


Patrons créateurs

But : Définir un mécanisme de création de classes ou d’objets.


Caractéristiques clés :
le patron encapsule (masque) la connaissance des classes concrètes
le patron masque comment leurs instances sont créées et combinées.
Conséquence : Un modèle créateur offre une grande liberté concernant :
quels objets doivent être créés
qui doit les créer
comment les créer
quand les créer

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 35 / 128


Patrons créateurs

Monteur
Fabrique
Fabrique abstraite
Prototype
Singleton

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 36 / 128


Monteur (Builder)

Intention
Dissocier la construction d’un objet complexe de sa représentation, de
sorte que le même processus de construction permette des
représentations différentes.
Alias : —
Indications d’utilisation
I l’algorithme de création d’un objet complexe doit être indépendant des
parties qui composent l’objet et de la manière dont ces parties sont
agencées
I le processus de construction doit autoriser des représentations différentes
de l’objet en construction
Exemple :
I Créer un message électronique à partir du destinataire, de l’expéditeur, de
l’objet, du texte, des fichiers attachés, etc.

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 37 / 128


Monteur (Builder)
Diagramme de classe

Directeur Monteur
construire construirePartie

pour chaque objet de la structure { MonteurConcret


monteur−>construirePartie()
construirePartie Produit
}
getRésultat

MessageBuilder
Exemple : Créer un message
setTo(String)
électronique (Produit) en précisant le
setObject(String)
destinaire, l’objet, le texte, les fichiers
...
attachés, etc. (construire les parties).
getMessage(): Message

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 38 / 128


Patrons créateurs

Monteur
Fabrique
Fabrique abstraite
Prototype
Singleton

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 39 / 128


Fabrique (Factory method)
Intention
I définir une interface pour la création d’un objet mais en laissant à des
sous-classes le choix des classes à instancier.
I permettre à une classe de déléguer la création d’objets à des sous-classes.
Alias : Fabrication, Constructeur polymorphe (ou virtuel)
Indications d’utilisation
I une classe ne peut pas prévoir les classes des objets qu’elle aura à créer
I une classe attend de ses sous-classes qu’elles spécifient les objets qu’elles
créent
Exemples :
I Créer un document qui peut être texte, dessin ou présentation en fonction
du nom du type de document.
On veut pouvoir ajouter de nouveaux types de documents.
I Obtenir un manipulateur sur des objets graphiques.
Conséquence :
I Il procure un gîte pour les sous-classes (objets élargis)
I Il inter-connecte des hiérarchies parallèles de classes.

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 40 / 128


Fabrique (Factory method)
Diagramme de classe

Créateur

fabriquer(): Product Product

CréateurConcret
fabriquer(): Product ProductConcret

Exemple : Créer une pizza en fonction de son nom : régina, calzone,


savoyarde...

Autre exemple : La méthode iterator() de Iterable.

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 41 / 128


Patrons créateurs

Monteur
Fabrique
Fabrique abstraite
Prototype
Singleton

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 42 / 128


Fabrique abstraite (Abstract Factory)

Intention
Fournir une interface pour la création de familles d’objets apparentés
ou interdépendants, sans qu’il soit nécessaire de spécifier leurs classes
concrètes.
Alias : Kit
Indications d’utilisation
I un système doit être indépendant de la manière dont ses produits ont été
construits, combinés ou représentés
I un système est composé à partir d’une famille de produits, parmi plusieurs
I on souhaite renforcer le caractère de communauté d’une famille de
produits conçus pour être utilisés ensemble
Exemples : boîte à outils proposant plusieurs « look-and-feel »
(décors).
Solution (principe) : définir une interface Fabrique qui déclare les
méthodes créerAscenceur, créerFenêtre, etc.

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 43 / 128


Fabrique abstraite (Abstract Factory)
Exemple : toolkit pour interfaces graphiques utilisateur (GUI)

FabriqueGUI Client

créerBouton()
créerFenêtre() Bouton

FabriqueMotif
BoutonMotif BoutonWin

créerBouton()
créerFenêtre()

FabriqueWin Fenêtre

créerBouton()
créerFenêtre()
FenêtreMotif FenêtreWin

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 44 / 128


Fabrique abstraite (Abstract Factory)
Diagramme de classe

FabriqueAbstraite Client

créerProduitA()
créerProduitB() ProduitAbstraitA

FabriqueConcrète1
ProduitA1 ProduitA2

créerProduitA()
créerProduitB()

FabriqueConcrète2 ProduitAbstraitB

créerProduitA()
créerProduitB()
ProduitB1 ProduitB2

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 45 / 128


Patrons créateurs

Monteur
Fabrique
Fabrique abstraite
Prototype
Singleton

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 46 / 128


Prototype

Intention
Spécifie le type des objets à créer par une instance (le prototype) et
crée de nouveaux objets en copiant ce prototype (clonage).
Alias : —
Indications d’utilisation
I classes à instancier spécifiées à l’exécution (p.ex. chargement
dynamique).
I éviter de construire une hiérachie de classes Fabrique
I classes pouvant prendre un nombre réduit d’états (un prototype par état)
Exemples :
I Éditeur de musique : les notes sont disponibles et copiées avant utilisation
I Éditeur UML : les éléments apparaissent dans un menu et sont copiés pour
les ajouter sur le dessin (puis les adapter).

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 47 / 128


Prototype
Diagramme de classe

Directeur prototype Prototype


construire clone()

p = prototype.clone()

PrototypeConcret1 PrototypeConcret2

clone() clone()

Exemple vu : Pour ajouter des commandes réversibles aux menus


textuels, il ne faut pas exécuter directement la commande obtenue du
menu mais une copie de cette commande (mémorisation des informations
pour pouvoir annuler).

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 48 / 128


Patrons créateurs

Monteur
Fabrique
Fabrique abstraite
Prototype
Singleton

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 49 / 128


Singleton

Intention
Garantir qu’une classe n’a qu’une seule instance et
fournir un point d’accès global à cette instance.
Alias : —
Indications d’utilisation
I Il doit y avoir exactement une instance d’une classe
I Cette instance doit être accessible globalement
I Le type du singleton peut-être sous-classé
=⇒ la classe elle-même est responsable de gérer l’unicité de l’objet et
son accès
Exemples : gestionnaire de fenêtres, file d’impression, etc.

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 50 / 128


Singleton
Diagramme de classe

1 /** Manière simple et traditionnelle de faire


2 * un Singleton en Java.
3 * Attention : non sûre si utilisation de threads
4 */
5 public class Singleton {
Singleton 6 private final static Singleton INSTANCE =
7 new Singleton();
− instanceUnique: Singleton 8

− donnéesSingleton 9 // Interdire toute création d’instance


+ getInstance(): Singleton 10 // depuis une classe extérieure
11 private Singleton() {}
+ operation(...) 12

− Singleton() 13 // Accès à l’instance unique


14 public static Singleton getInstance() {
15 return INSTANCE;
16 }
17

18 }

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 51 / 128


Sommaire

1 Pourquoi les patrons ? Adaptateur


Pont
2 Patrons fondamentaux Composite
Décorateur
3 Patrons créateurs Façade
Poids mouche
4 Patrons structurels Procuration
Discussion
5 Patrons comportementaux

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 52 / 128


Patrons structurels

Définir la façon d’assembler des classes et des objets pour réaliser des
structures complexes.
Agrégat d’objets conçus comme des « macro-composants ».

Patrons présentés :
Adaptateur
Pont
Composite
Décorateur
Façade
Poids mouche
Procuration
Discussion

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 53 / 128


Patrons structurels

Adaptateur
Pont
Composite
Décorateur
Façade
Poids mouche
Procuration
Discussion

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 54 / 128


Adaptateur (Adapter)

Intention
Convertit l’interface d’une classe en une autre conforme à l’attente
d’un client.
Permet de faire collaborer des classes aux interfaces incompatibles.
Alias : Empaqueteur (Wrapper)
Indications d’utilisation
I On veut utiliser une classe dont l’interface ne coïncide pas avec celle
escomptée
I Prévoir l’ajout de classes non encore connues
Exemples :
I Utiliser un ArrayList pour réaliser une Pile (Adaptation d’objet).
I Restructuration de Vector avec List (Adaptation de classe)

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 55 / 128


Adaptateur (Adapter)
Diagramme de classe pour l’Adaptateur de Classe

Client But Adapté


requête() requêteSpécifique()

«implantation»

Adapteur
requêteSpécifique()
requête()

Exemple : SousMenu dans l’éditeur avec menu textuel

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 56 / 128


Adaptateur (Adapter)
Diagramme de classe pour l’Adaptateur d’Objet

Client But Adapté


adapté
requête() requêteSpécifique()

Adapteur
requêteSpécifique()
requête()

Exemple : CommandeGérerMenu dans l’éditeur avec menu textuel

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 57 / 128


Patrons structurels

Adaptateur
Pont
Composite
Décorateur
Façade
Poids mouche
Procuration
Discussion

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 58 / 128


Pont (Bridge)
Intention
Découple une abstraction de sa réalisation afin que les deux puissent être
modifiées indépendamment de l’autre
Alias : Poignée/Corps (Handler/Body)
Indications d’utilisation
I éviter un lien définitif entre une abstraction et son implantation
I permettre la spécialisation des abstractions et des implantations
I un changement de l’implantation ne doit pas avoir d’impact sur les clients
I plusieurs objets partagent la même implantation mais ceci est transparent
pour les clients (compteur de références)
Exemples :
I Objets géométriques variés devant être affichés sur différents écrans.
I L’abstraction Voiture doit pouvoir rouler sur une route (implantation).
Tout type de voiture doit pouvoir rouler sur tout type de route.
Conséquences :
I découplage entre abstraction et implantation
I capacité d’extension accrue
I dissimulation des détails d’implantation aux clients
Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 59 / 128
Pont (Bridge)
Diagramme de classe

Directeur impl Implanteur


opération opérationImpl()

imp.opérationImpl()

ImplanteurConcret1 ImplanteurConcret2
AbstractionFine
opérationImpl() opérationImpl()

Exemple : Dessiner (opération) les objets géométriques (abstraction) sur


un afficheur (implantation).

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 60 / 128


Patrons structurels

Adaptateur
Pont
Composite
Décorateur
Façade
Poids mouche
Procuration
Discussion

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 61 / 128


Composite

Intention
I Compose des objets en des structures arborescentes pour représenter des
hiérarchies composant/composé.
I Permet au client de traiter uniformément un objet individuel ou les
combinaisons de ceux-ci
Alias : —
Indications d’utilisation
I représentation de structures récursives d’éléments hétérogènes
I traitement uniforme d’un objet individuel ou d’une combinaison d’objets
Exemples : Groupe dans éditeur de schémas mathématiques.
Conséquences :
+ facilite l’ajout de nouveaux types de composants
– difficile d’imposer des contraintes sur les compositions possibles

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 62 / 128


Composite
Diagramme de classe

Composant
enfant
Client opération()
0..*
getEnfant(int)
ajouter(Composant)
supprimer(Composant)

Feuille Composite

opération()
opération() for (Composant c: enfants) {
getEnfant(int) c.opération()
ajouter(Composant)
}
supprimer(Composant)

Attention : les opérations manipulant les composés peuvent ou non être


remontées au niveau du composant : compromis entre sécurité et
transparence (pour le client)

Exemple : Groupe d’objets géométriques.

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 63 / 128


Patrons structurels

Adaptateur
Pont
Composite
Décorateur
Façade
Poids mouche
Procuration
Discussion

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 64 / 128


Décorateur (Decorator)
Intention
I Attache dynamiquement des responsabilités supplémentaires à un objet
I Alternative souple à l’héritage pour ajouter de nouvelles fonctionnalités
Alias : Emballeur (Wrapper)
Indications d’utilisation
I ajouter dynamiquement de nouvelles fonctionnalités, de manière
transparente (sans changement d’interface)
I définir des responsabilités qui peuvent être ajoutées/retirées
I éviter un héritage impossible à cause du trop grand nombre d’extensions
indépendantes possibles
Exemples :
I Éléments optionnels (bord, ascenseur...) sur un composant graphique
I Flots d’entrée/sorties en Java (aussi appelé Filtre dans ce cas).
Conséquences :
I plus de souplesse que l’héritage (qui est statique)
I évite de surcharger en fonctionnalités les classes de haut niveau
I composant et composant décoré n’ont pas la même identité (adresse) !
I de nombreux petits objets !
Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 65 / 128
Décorateur (Decorator)
Diagramme de classe

Composant − leComposant

+ opération()

ComposantConcret Décorator

+ opération() + opération() code:


leComposant.opération()

DécorateurConcretA DécorateurConcretB

+ opération() − otherAttribute
+ otherOperation() + opération()

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 66 / 128


Décorateur (Decorator)
Diagramme de séquence

: Test

« create »
comp : ComposantConcret

« create » (comp)
dec : DécorateurConcretA
opération()
opération()

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 67 / 128


Décorateur (Decorator)
Exemple : élément graphique avec décorations

JComponent

# paintComponent(g: Graphics) − component

MyPanel Decorator

+ MyPanel(title: String) # paintComponent(g: Graphics)


# paintComponent(g: Graphics)

ScrollBarDecorator BorderDecorator
1 JComponent c =
− couleur: java::awt::Color
2 new BorderDecorateur(
+ BorderDecorator(component_: JComponent,
3 new ScrollBarDecorateur(
couleur_: java::awt::Color)
4 new MyPanel())); + setCouleur(couleur_: java::awt::Color)
+ getCouleur(): java::awt::Color
# paintComponent(g: Graphics)

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 68 / 128


Patrons structurels

Adaptateur
Pont
Composite
Décorateur
Façade
Poids mouche
Procuration
Discussion

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 69 / 128


Façade (Facade)

Intention
Fournit une interface unifiée pour un sous-système, interface de haut
niveau rendant le système plus facile à utiliser (couplage réduit).
Alias : —
Indications d’utilisation
I On souhaite disposer d’une interface simple pour un système complexe
I diminuer le couplage entre un sous-système et les clients
I structuration d’un sous-système en niveaux
Exemple :
Un compilateur (compiler) qui utilise l’analyseur lexical, l’analyseur
syntaxique, l’analyseur sémantique, une table des symboles, engendre du
code pour plusieurs architectures, etc.

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 70 / 128


Façade (Facade)
Diagramme de classe

classes client

Façade

sous−système

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 71 / 128


Patrons structurels

Adaptateur
Pont
Composite
Décorateur
Façade
Poids mouche
Procuration
Discussion

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 72 / 128


Poids mouche (Flyweight)
Intention
Utilise une technique de partage permettant la mise en œuvre efficace
d’un grand nombre d’objets de granularité fine.
Alias : —
Indications d’utilisation
I Détérioration des performances due à un trop grand nombre de petits
objets (coût de stockage élevé)
I Distinction possible entre état intrinsèque et extrinsèque (fonction du
contexte client)
I Partage possible des états intrinsèques.
Exemples :
I Analyse lexicale : unités lexicales gérées comme des poids mouches
F état intrinsèque : la chaîne
F état extrinsèque : ligne et colonne du premier caractère

Implantation :
I déportation des états extrinsèques
I gestion des objets partagés

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 73 / 128


Poids mouche (Flyweight)
Diagramme de classe

FabriqueDePoidsMouche PoidsMouche
*

getPoidsMouche(touche) operation(etatExtrinseque)

si poidsMouche(touche) existe {
return poids mouche existant
} sinon {
créer un nouveau poids mouche
l’ajouter au parc à poids mouches
return nouveau poids mouche
}

PoidsMoucheConcret PoidsMoucheConcretNonPartagé
Client
étatIntrinsèque toutEtat
operation(etatExtrinseque) operation(etatExtrinseque)

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 74 / 128


Patrons structurels

Adaptateur
Pont
Composite
Décorateur
Façade
Poids mouche
Procuration
Discussion

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 75 / 128


Procuration (Proxy)

Intention
Fournit à un client un mandataire ou un remplaçant pour contrôler l’accès
à un objet fournisseur
Alias : Subrogé (Surrogate), Mandataire, Procuration
Indications d’utilisation
I procuration à distance : représentant local d’un objet distant
I procuration virtuelle : création d’objet à la demande
I procuration de protection : contrôle les accès au fournisseur
I référence intelligente (smart pointer) : remplaçant d’un pointeur brut qui
ajoute compteur de références, chargement en mémoire d’un objet
persistant...

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 76 / 128


Procuration (Proxy)
Diagramme de classe

Sujet
Client
requête

...
SujetRéel Procuration
sujetRéel.requête()
requête sujetRéel
requête ...

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 77 / 128


Patrons structurels

Adaptateur
Pont
Composite
Décorateur
Façade
Poids mouche
Procuration
Discussion

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 78 / 128


Patrons structurels
Discussion

Similitudes entre ces patrons mais des intentions différentes !


Mécanismes communs :
I héritage : pour les patrons dont le domaine est classe
I délégation : pour les patrons dont le domaine est objet
Adapteur et Pont : indirection et ré-expédition de requêtes entre une
interface et une réalisation
Façade : construction d’une nouvelle interface
Composite et Décorateur : agrégats récursifs

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 79 / 128


Sommaire

Chaîne de responsabilités
1 Pourquoi les patrons ? Commande
Interpréteur
Itérateur
2 Patrons fondamentaux
Médiateur
Mémento
3 Patrons créateurs
Observateur
État
4 Patrons structurels
Stratégie
Patron de méthode
5 Patrons comportementaux
Visiteur

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 80 / 128


Patrons comportementaux

Chaîne de responsabilités
Commande
Interpréteur
Itérateur
Médiateur
Mémento
Observateur
État
Stratégie
Patron de méthode
Visiteur

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 81 / 128


Chaîne de responsabilités (Chain of Responsibility)
Intention
I Évite le couplage entre l’émetteur d’une requête et ses récepteurs
I Chaîne les récepteurs qui se passent la requête jusqu’à ce qu’un la traite
(le gestionnaire)

Alias : —
Indications d’utilisation
I Une requête peut être gérée par plus d’un objet à la fois et le gestionnaire
n’est pas connu a priori (déterminé dynamiquement)
I On souhaite adresser une requête à plusieurs objets, sans spécifier
explicitement le récepteur
I Les objets qui traitent la demande doivent être définis dynamiquement
Exemples :
I même principe que les exceptions Java : récepteurs = catch
Conséquences :
I Réduction du couplage
I Souplesse accrue dans l’attribution des responsabilités
I Pas de garantie de traitement de la requête !

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 82 / 128


Chaîne de responsabilités (Chain of Responsibility)
Diagramme de classe

successeur

Gestionnaire
Client
gérerRequête

GestionnaireConcret1 GestionnaireConcret2

gérerRequête gérerRequête

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 83 / 128


Patrons comportementaux

Chaîne de responsabilités
Commande
Interpréteur
Itérateur
Médiateur
Mémento
Observateur
État
Stratégie
Patron de méthode
Visiteur

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 84 / 128


Commande (Command)

Intention
I encapsuler une requête (ou un traitement) comme un objet (version objet
des callbacks)
I paramétrer le contexte client
I gestion possible des requêtes/traitements en FIFO, annulation possible.
Alias : Action, Transaction
Indications d’utilisation :
I réaliser un principe de callback
I permettre de mémoriser des modifications
I structurer le système en opérations de haut niveau (transaction)
I voir aussi Intention

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 85 / 128


Commande (Command)
Diagramme de classe

Invocateur Commande
exécuter()

Client

Récepteur CommandeConcrète
action() exécuter() récepteur−>action()

état

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 86 / 128


Patrons comportementaux

Chaîne de responsabilités
Commande
Interpréteur
Itérateur
Médiateur
Mémento
Observateur
État
Stratégie
Patron de méthode
Visiteur

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 87 / 128


Interpréteur (Interpreter)

Intention
Définit une représentation de la grammaire d’un langage simple ainsi
qu’un interpréteur.
Alias : —
Indications d’utilisation
I la grammaire du langage doit être simple
I l’efficacité n’est pas un souci majeur
Exemples : Évaluer une expression arithmétique
Conséquences :
I les grammaires complexes sont difficiles à maintenir
=⇒ utiliser des générateurs de compilateur (javacc, java_cup, antlr, etc.)

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 88 / 128


Patrons comportementaux

Chaîne de responsabilités
Commande
Interpréteur
Itérateur
Médiateur
Mémento
Observateur
État
Stratégie
Patron de méthode
Visiteur

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 89 / 128


Itérateur (Iterator)

Intention
Fournit un moyen pour accéder séquentiellement à chacun des éléments
d’un agrégat d’objets sans révéler la représentation interne de l’agrégat
Alias : Curseur (Cursor)
Indications d’utilisation
I accéder aux éléments d’un agrégat sans révéler sa structure interne
I gérer simultanément plusieurs parcours sur des agrégats
I offrir une interface uniforme pour parcourir différents types d’agrégats
Exemples :
I Les itérateurs des collections Java
Conséquences :
I possibilité de définir plusieurs parcours (infixe et préfixe par exemple)
I simplification de l’interface de l’agrégat
I parcours simultanés possibles sur un même agrégat

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 90 / 128


Itérateur (Iterator)
Diagramme de classe

<<utilise>>
<< interface >> OutilsListe
Itérateur
«interface» somme(liste: Liste): double
Liste
suivant(): T
encore(): boolean

ItérateurTab
ListeTab
suivant(): T suivante 0..1
encore(): boolean
ItérateurChainé Cellule
ListeChaînée − première
élément: double 0..1
suivant(): T 0..1
encore(): boolean

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 91 / 128


Patrons comportementaux

Chaîne de responsabilités
Commande
Interpréteur
Itérateur
Médiateur
Mémento
Observateur
État
Stratégie
Patron de méthode
Visiteur

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 92 / 128


Médiateur (Mediator)
Intention
I Définit un objet encapsulant les modalités d’interaction d’autres objets
I Limite le couplage car évite une référence explicite entre ces objets
Alias : —
Indications d’utilisation
I Les objets d’un ensemble communiquent d’une façon bien définie mais
complexe : inter-dépendances non structurées et difficiles à appréhender
I Réutilisation difficile d’un objet car fait référence à beaucoup d’objets
I Un comportement distribué entre plusieurs classes doit pouvoir être
spécialisé sans multiplier les sous-classes
Exemple : médiateur entre les éléments graphiques d’une boîte de dialogue
Conséquences :
I limite la création de sous-classes (seulement du médiateur, pas des
collègues)
I réduit le couplage entre collègues
I simplifie les protocoles objet (interaction 1–plusieurs)
I formalise la coopération des objets
I centralise le contrôle
Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 93 / 128
Médiateur (Mediator)
Diagramme de classe

médiateur
Médiateur Collègue

MédiateurConcret CollègueConcret1 CollègueConcret2

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 94 / 128


Patrons comportementaux

Chaîne de responsabilités
Commande
Interpréteur
Itérateur
Médiateur
Mémento
Observateur
État
Stratégie
Patron de méthode
Visiteur

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 95 / 128


Mémento (Memento)
Intention
Transmettre à l’extérieur d’un objet son état interne sans violation de
l’encapsulation dans le but de restaurer ultérieurement sont état.
Alias : Jeton
Indications d’utilisation
I un instantané de tout ou partie d’un objet doit être mémorisé
I et l’utilisation d’une interface directe pour atteindre l’état conduirait à
rompre l’encapsulation
Exemples :
I Pouvoir passer les niveaux déjà atteints dans un jeu
I Déplacer des objets graphiques reliés. Classe Résolution des contraintes.
Nécessité de collaborer avec Résolution pour annuler.
Conséquences :
I préservation des frontières de l’encapsulation
I simplification de l’auteur (car encapsulation préservée)
I l’utilisation d’un mémento peut être coûteuse
I peut être difficile de garantir que seul l’auteur aura accès au mémento

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 96 / 128


Mémento (Memento)
Diagramme de classe

Auteur Mémento Surveillant


état état

installerMémento(m: Mémento) getEtat()


créerMémento(): Mémento Mémento(état)

return new Mémento(état) état = m.getEtat()

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 97 / 128


Patrons comportementaux

Chaîne de responsabilités
Commande
Interpréteur
Itérateur
Médiateur
Mémento
Observateur
État
Stratégie
Patron de méthode
Visiteur

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 98 / 128


Observateur (Observer)

Intention
Définit une interdépendance de type un à plusieurs de sorte que quand un
objet change d’état, tous ceux qui en dépendent en soient avertis et
automatiquement mis à jour
Alias : Dépendants, Diffusion–Souscription (Publish–Subscribe)
Indications d’utilisation
I Pour faciliter la réutilisation de deux représentations inter-dépendantes
d’un même concept
I Quand la modification d’un objet nécessite de modifier un nombre
indéterminé d’autres objets
I Quand un objet doit notifier d’autres objets sans faire d’hypothèses sur la
nature de ces objets (faible couplage)
Exemples : Plusieurs vues sur un même modèle

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 99 / 128


Observateur (Observer)
Diagramme de classe

Sujet Observateur
observateurs
+ inscrire (o : Observateur) 0..* + mettreAJour()
+ annuler (o : Observateur)
# avertir()

for(Observateur s: observateurs) {
o.mettreAJour();
}

SujetConcret ObservateurConcret
sujet
getEtat()
mettreAJour
etat

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 100 / 128


Observateur (Observer)
Exemple

Observable Observateur
observateurs
+ inscrire (o : Observateur) 0..* + mettreAJour()
+ annuler (o : Observateur)
# avertir()

for (Observateur o: observateurs) {


o.mettreAJour();
}

2 *
Point Segment
− extremite1,
− extremite2

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 101 / 128


Patrons comportementaux

Chaîne de responsabilités
Commande
Interpréteur
Itérateur
Médiateur
Mémento
Observateur
État
Stratégie
Patron de méthode
Visiteur

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 102 / 128


État (State)
Intention
Permet à un objet de modifier son comportement quand son état
interne change. Donne l’impression que l’objet change de classe.
Alias : —
Indications d’utilisation
I le comportement d’un objet dépend de son état (changement dynamique)
I les opérations contiennent des conditionnelles en fonction de l’état de
l’objet
Exemples :
I Le joueur d’une équipe de foot (presque !)
I Une ConnexionTCP qui répondra différemment à une demande d’ouverture
suivant son état (établie, écoute, fermée).
Conséquence :
I Partionnement des différents comportements, état par état
I Rend explicite les transitions d’état
I Les objets État peuvent être partagés (si pas d’attributs d’instance) : poids
mouche

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 103 / 128


État (State)
Diagramme de classe

état État
Contexte
gérer()
requete()

état.gérer()

ÉtatConcretA ÉtatConcretB

gérer() gérer()

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 104 / 128


Patrons comportementaux

Chaîne de responsabilités
Commande
Interpréteur
Itérateur
Médiateur
Mémento
Observateur
État
Stratégie
Patron de méthode
Visiteur

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 105 / 128


Stratégie (Strategy)

Intention
I Définit une famille d’algorithme, encapsule chacun d’entre eux et les rend
interchangeables.
I Permet aux algorithmes d’évoluer indépendamment de leurs clients
Alias : Politique
Indications d’utilisation
I Plusieurs classes apparentées ne différent que par leur comportement
I On a besoin de diverses variantes d’un algorithme.
I Un algorithme utilise des données que les clients n’ont pas à connaître
(masquer les structures complexes)
I Une classe définit de nombreux comportements figurant dans des
conditionnelles multiples : faire autant de classes Stratégie
Exemples :
I Gérer les coupures de fin de ligne
I trier les éléments d’une collection

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 106 / 128


Stratégie (Strategy)
Diagramme de classe

stratégie Stratégie
Contexte
interfaceContexte() interfaceAlgorithme()

stratégie.interfaceAlgorithme()

StratégieConcrèteA StratégieConcrèteB

interfaceAlgorithme() interfaceAlgorithme()

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 107 / 128


Patrons comportementaux

Chaîne de responsabilités
Commande
Interpréteur
Itérateur
Médiateur
Mémento
Observateur
État
Stratégie
Patron de méthode
Visiteur

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 108 / 128


Patron de méthode (Template Method)

Intention
Définit, dans une opération, le squelette d’un algorithme en en
déléguant certaines étapes à des sous-classes.
Alias : —
Indications d’utilisation
I Pour implanter une fois pour toutes les parties invariantes d’un algorithme
I Pour isoler et factoriser le comportement comment à des sous-classes
I contrôler les extensions des sous-classes (garantir un certain
comportement)
Exemples :
I exécuter un test unitaire avec préparer (setUp), tester (test*) et
comptabiliser le résultat du test et nettoyer (tearDown).

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 109 / 128


Patron de méthode (Template Method)
Diagramme de classe

ClasseAbstraite

patronMethode() ...
opérationPrimitive1() opérationPrimitive1()
opérationPrimitive2() ...
opérationPrimitive2()
...

ClasseConcrète
opérationPrimitive1()
opérationPrimitive2()

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 110 / 128


Patrons comportementaux

Chaîne de responsabilités
Commande
Interpréteur
Itérateur
Médiateur
Mémento
Observateur
État
Stratégie
Patron de méthode
Visiteur

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 111 / 128


Visiteur (Visitor)

Intention
Modélise par une classe une opération applicable aux éléments d’une
structure d’objets et permet de définir de nouvelles opérations sans
modifier les classes de la structure
Alias : —
Indications d’utilisation
I Une structure d’objets contient beaucoup de classes différentes
d’interfaces distinctes et l’on veut réaliser des traitements qui dépendent
de leurs classes concrètes.
I Il s’agit de réaliser plusieurs traitements distincts sans relation entre eux,
sur les objets de la structure, sans polluer leurs classes
I Les classes qui définissent la structure d’objet changent rarement mais on
doit souvent définir de nouvelles opérations sur cette struture.
Exemples : Afficher en infixe, préfixe et postfixe une expression
entière, calculer sa valeur, etc.

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 112 / 128


Visiteur (Visitor)
Visiteur
Diagramme de classe
visiterÉlémentA1(ÉlémentA1))
visiterÉlémentA2(ÉlémentA2)
visiterÉlémentB(ÉlémentB)

VisiteurConcret1 VisiteurConcret2

visiterÉlémentA1(ÉlémentA1)) visiterÉlémentA1(ÉlémentA1))
visiterÉlémentA2(ÉlémentA2) visiterÉlémentA2(ÉlémentA2)
visiterÉlémentB(ÉlémentB) visiterÉlémentB(ÉlémentB)

Client ÉlémentAbstraitA
StructureDObjets accepter(v:Visiteur)

ÉlémentB ÉlémentA1 ÉlémentA2


accepter(v:Visiteur) accepter(v:Visiteur) accepter(v:Visiteur)
opérationB() opérationA1() opérationA2()

v.visiterÉlémentB(this) v.visiterÉlémentA1(this) v.visiterÉlémentA2(this)

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 113 / 128


Visiteur appliqué aux objets géométriques :
problème posé
Diagramme de classe structurel des objets géométriques :
*
ObjetGéométrique
élément

Cercle 1
Point 2
x Segment Groupe
rayon centre
y e1, e2

PointNommé
nom

Traitements à implanter :

1 obtenir le nom en français d’un 4 afficher un élément


élément : segment, point... 5 dessiner un élément
2 obtenir le nom en anglais 6 translater un élément
3 nombre de points utilisés pour 7 obtenir la bounding box d’un
caractériser un élément élément

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 114 / 128


Solution objet « classique »
Principe : Pour chaque opération, mettre une méthode sur les types
généraux (ObjetGéométrique et Point) et la (re)définir dans les sous-classes.

ObjetGéométrique
*
nom(): String
nbPoints(): int élément
translater(dx, dy)

Cercle Point
Segment Groupe
rayon x
1 y 2
nom(): String nom(): String nom(): String
centre nom(): String e1, e2 nbPoints(): int nbPoints(): int
nbPoints(): int nbPoints(): int
translater(dx, dy) translater(dx, dy) translater(dx, dy)
translater(dx, dy)

PointNommé
nom
nom(): String

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 115 / 128


Problèmes induits par cette solution

Solution opérationnelle mais :


chaque traitement est éclaté sous l’ensemble de la structure de classes
la structure est polluée par les différents traitements
il faut pouvoir modifier les classes pour ajouter de nouveaux
traitements

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 116 / 128


Principe du visiteur

Principe : Écrire une classe par traitement.


Moyen :
I regrouper dans une classe traitement les méthodes implantant ce
traitement
I mettre un paramètre explicite correspond à la classe traitée
I rendre accessibles les informations internes de la structure (accesseurs)
Nouveau diagramme de classe : diagramme structurel initial +

NomFrançais NombrePoints Translateur

nom(p: Point): String nbPoints(p: Point): int translater(p: Point, dx, dy)
nom(pn: PN): String nbPoints(pn: PN): int translater(pn: PN, dx, dy)
nom(s: Segment): String nbPoints(s: Segment): int translater(s: Segment, dx, dy)
nom(c: Cercle): String nbPoints(c: Cercle): int translater(c: Cercle, dx, dy)
nom(g: Groupe): String nbPoints(g: Groupe): int translater(g: Groupe, dx, dy)

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 117 / 128


Traitements NomFrancais et NomAnglais : pas de
problème
1 public class NomFrancais {
2 public String nom(Point p) { return "point"; }
3 public String nom(PointNomme pn) { return "point nommé"; }
4 public String nom(Segment s) { return "segment"; }
5 public String nom(Cercle c) { return "cercle"; }
6 public String nom(Groupe g) { return "groupe"; }
7 }

1 public class NomAnglais {


2 public String nom(Point p) { return "point"; }
3 public String nom(PointNomme pn) { return "named point"; }
4 public String nom(Segment s) { return "segment"; }
5 public String nom(Cercle c) { return "circle"; }
6 public String nom(Groupe g) { return "group"; }
7 }

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 118 / 128


Traitement NombrePoints : pas si facile !
1 public class NombrePoints {
2 public int nbPoints(Point p) { return 1; }
3 public int nbPoints(PointNomme pn) { return 1; }
4 public int nbPoints(Segment s) { return 2; }
5 public int nbPoints(Cercle c) { return 1; }
6 public int nbPoints(Groupe g) {
7 int somme = 0;
8 for (ObjetGeometrique og : g.elements()) {
9 if (og instanceof Segment) {
10 somme += nbPoints((Segment) og);
11 } else if (og instanceof Cercle) {
12 somme += nbPoints((Cercle) og);
13 } else if (og instanceof Groupe) {
14 somme += this.nbPoints((Groupe) og);
15 } else {
16 throw new RuntimeException("Erreur dans le traitement par cas !");
17 }
18 }
19 return somme;
20 }
21 } Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 119 / 128
Critiques et... une solution
Ça marche mais :
I Faire des instanceof est une mauvaise idée !
=⇒ voir l’exception levée...
I De nombreux traitements nécessitent ce traitement par cas : afficher,
translater, dessiner, bounding box, etc.
On sait comment faire pour l’éviter !
I Il suffit de mettre une méthode correspondant au traitement fait dans le
type général et la redéfinir dans les sous-classes....
I MAIS on retombe sur la solution initiale :(
Solution :
I C’est bien en ajoutant une méthode sur les classes de la structure que l’on
peut faire la sélection de la bonne méthode sans instanceof
I L’idée est de ne définir qu’une seule méthode, et non une par traitement
I Il faut généraliser les différents traitements : c’est le Traitement/Visiteur !
I Il faut unifier le nom des méthodes : traiter/visiter
I Le type de retour change ? La généricité
I Et la méthode sur ObjetGéometrique ?
exécuter(Traitement)/accepter(Visiteur)

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 120 / 128


L’architecture du Visiteur
ObjetGéométrique «interface»
* Traitement<R>
élément
<R> R exécuter(Traitement<R>) traiter(p: Point): R
traiter(pn: PN): R
traiter(s: Segment): R
Point traiter(c: Cercle): R
Cercle Segment Groupe
1 x 2 traiter(g: Groupe): R
rayon y
centre e1, e2
exécuter exécuter exécuter exécuter

PointNommé
nom
exécuter

Translateur
NomFrançais NombrePoints
dx, dy: double
traiter(p: Point): String traiter(p: Point): Integer traiter(p: Point)
traiter(pn: PN): String traiter(pn: PN): Integer traiter(pn: PN)
traiter(s: Segment): String traiter(s: Segment): Integer traiter(s: Segment)
traiter(c: Cercle): String traiter(c: Cercle): Integer traiter(c: Cercle)
traiter(g: Groupe): String traiter(g: Groupe): Integer traiter(g: Groupe)

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 121 / 128


Un peu de code...
l’interface Traitement
1 public interface Traitement<R> {
2 R traiter(Point p);
3 R traiter(PointNomme pn);
4 R traiter(Segment s);
5 R traiter(Cercle c);
6 R traiter(Groupe g);
7 }
Le code de exécuter dans les interfaces et classes abstraites :
1 abstract public <R> R exécuter(Traitement<R> t);
Le code de exécuter dans les classes concrètes :
1 public class Cercle {
2 public <R> R exécuter(Traitement<R> t) {
3 return t.traiter(this);
4 }
5 ...
6 }
Xavier...
7 Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 122 / 128
Un peu de code : traitement NombrePoints

1 public class NombrePoints implements Traitement<Integer> {


2 Integer traiter(Point p) { return 1; }
3 Integer traiter(PointNomme pn) { return 1; }
4 Integer traiter(Segment s) { return 2; }
5 Integer traiter(Cercle c) { return 1; }
6 Integer traiter(Groupe g) {
7 int somme = 0;
8 for (ObjetGeometrique og : g.elements()) {
9 somme += og.executer(this);
10 }
11 return somme;
12 }
13 }

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 123 / 128


Utiliser un visiteur
1 Point p1 = new Point(10, −2);
2 Point p2 = new PointNomme(3, 4, "A");
3 Segment s = new Segment(p1, p2);
4 Cercle c = new Cercle(new Point(1, 2), 10);
5 Groupe g = new Groupe();
6 g.ajouter(s);
7 g.ajouter(c);
8 ObjetGeometrique og = g;
9 Traitement<Integer> compteur = new NombrePoints();
10 int nbPoints;
11 nbPoints = g.executer(compteur); // ???
12 nbPoints = og.executer(compteur); // ???
13 nbPoints = compteur.traiter(g); // ???
14 nbPoints = compteur.traiter(og); // ???
15 Traitement<String> nf = new NomFrancais();
16 String nom;
17 nom = p2.executer(nf); // ???
18 nom = nf.traiter(p2); // ???
Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 124 / 128
Visiteur appliqué aux objets géométriques
Diagramme de séquence de g.exécuter(compteur)

main g: Groupe c: Cercle compteur s: Segment

exécuter(compteur)
traiter(g)
exécuter(compteur) {somme = 0}
traiter(c)
1
1 {somme = 1}
exécuter(compteur)
traiter(s)
2
2
3 {somme = 3}

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 125 / 128


Visiteur (Visitor)
conséquences et implantation

Conséquences :
I il facilite l’ajout de nouveaux traitements
I un visiteur rassemble les opérations d’un même type (Visiteur concret)
I l’addition de nouvelles classes à la structure est difficile
I se promener dans une hiérarchie de classe : itérateur (partiel).
I thésaurisation des informations d’état dans un visiteur
I rupture d’encapsulation (interface des Éléments riche)
Implantation
I Double aiguillage : deux critères déterminent l’opération à effectuer, le
Visiteur et l’Élément.
I Qui organise le parcours de la structure d’objet :
F le visiteur
F la structure d’objet (souvent choisi)
F un itérateur à part

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 126 / 128


Patrons comportementaux : synthèse

Encapsultation des parties variables


I Stratégie : : un algorithme
I Patron de méthode : les étapes d’un algorithme
I État : un comportement dépendant de l’état
I Médiateur : un protocole
I Itérateur : le parcours d’un agrégat
Relations statiques supportant la communication
I Commande, Observateur, Médiateur, Chaîne de responsabilités :
découplage entre émetteur et récepteur
I Médiateur : communication encapsulée
I Observateur : communication distribuée

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 127 / 128


Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides.
Design Patterns.
Addison-Wesley Professional, January 1995.
Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides.
Design Patterns, Catalogue de modèles de conceptions réutilisables.
Vuibert, October 1999.
Mark Grand.
Patterns in Java: A Catalog of Reusable Design Patterns Illustrated with
UML, volume 1.
Wiley, 2 edition, 2002.
Wikipedia : Design Pattern.
http://en.wikipedia.org/wiki/Design_pattern_%28computer_
science%29.

Xavier Crégut (ENSEEIHT) Patrons de conception(Design Patterns) 128 / 128

Vous aimerez peut-être aussi