Академический Документы
Профессиональный Документы
Культура Документы
Jean-Yves Didier
didier@ufrst.univ-evry.fr
nextHandler.handleRequest()
Handler
Client - nextHandler : Handler Si la requête peut être traitée,
+ handleRequest() alors traiter la requête, sinon :
super.handleRequest()
ConcreteHandler1 ConcreteHandler2
+ handleRequest() + handleRequest()
1 Introduction
2 Patrons comportementaux
3 Patrons structuraux
4 Patrons créationnels
5 Les anti-patrons
Anti-patrons / anti-patterns
Diagnostic et résolution de dysfonctionnements
Nouveau contexte
Avantages Avantages
Avantages et supérieurs aux inférieurs aux
conséquences aléatoires inconvénients inconvénients
Définition
• Description d’une solution classique à un problème récurrent ;
• Forme de capitalisation de l’expérience en génie logiciel.
Avantages
• Vocabulaire formalisé ;
• Capitalisation de l’expérience ;
• Niveau d’abstraction élevé ;
• Complexité réduite ;
• Temps de conception et développement réduit ;
• Guide/catalogue de solutions.
Inconvénients
• Synthèse nécessaire :
I Comment reconnaı̂tre une situation où un patron s’applique ?
• Apprentissage :
I Catalogue volumineux : plus de 150 patrons répertoriés ;
Bref historique
• Description de la solution :
I Structure : diagramme de classes, de séquences,
I Participants (classes et objets) et collaborations,
I Description de la réalisation et exemple de code.
• Conséquences :
I Résultats, discussion avantages/inconvénients.
D’autres familles
Les patrons gérant la concurrence, GRASP, . . .
1 Introduction
2 Patrons comportementaux
3 Patrons structuraux
4 Patrons créationnels
5 Les anti-patrons
Dénominations
Chain of responsability (Chaı̂ne de responsabilité), CoR,
intercepting filter
Contexte d’application
• Objectif :
I Déléguer un traitement à qui saura le réaliser ;
I Établir une chaı̂ne de filtres travaillant sur les mêmes données.
• Utilisation : (moyennement faible)
I Permet à un nombre quelconque de classes d’essayer de
Architecture de la solution
nextHandler.handleRequest()
Handler
Client - nextHandler : Handler Si la requête peut être traitée,
+ handleRequest() alors traiter la requête, sinon :
super.handleRequest()
ConcreteHandler1 ConcreteHandler2
+ handleRequest() + handleRequest()
Entités participantes
• Client
I Classe requérant le traitement ;
I L’initie sur une des classes ConcreteHandler.
• Handler
I Définit une interface pour répondre aux requêtes ;
• ConcreteHandler
I S’occupe de la requête dont il peut se charger ;
I Peut accéder à son successeur ;
Exemples d’utilisation
• Première version de la gestion des évènements en AWT
(Java) :
I Les évènements souris et claviers sont passés successivement
aux widgets jusqu’à trouver celui qui traite l’évènement.
I Le patron observateur lui a finalement été préféré.
• Les filtres pour les servlets JEE
I Classe Filter standard dans le paquetage javax.servlet
(v2.3) ;
I Permet d’appliquer à la chaı̂nes plusieurs filtres sur le
Avantages
• Faible couplage entre celui qui envoie la requête et celui qui la
gère réellement ;
• La chaı̂ne peut être modifiée dynamiquement.
Inconvénients
• Ne garantit pas qu’un requête sera traitée ;
• Acroit dangereusement le nombre d’objets actifs.
Iterator (1/6)
Dénomations
Iterator (Iterateur), cursor
Contexte d’application
• Objectif :
I Parcourir les éléments contenus dans un autre objet.
• Utilisation : (Elevée)
I Permet de parcourir une collection d’objets pour accéder
Iterator (2/6)
Architecture de la solution
Collection Iterator
ConcreteCollection
ConcreteIterator
+ getIterator() : Iterator
Iterator (3/6)
Entités participantes
• Iterator
I Définit une interface pour accéder et voyager parmi les
éléments.
• ConcreteIterator
I Réalise l’interface Iterator ;
I Conserve sa position courante dans la collection d’objets.
• Collection
I Définit une interface pour créer un objet de type Iterator.
• ConcreteCollection
I Réalise l’interface de Collection pour retourner une instance
Iterator (4/6)
Exemples d’utilisation
• Classes de base en C++ ! !
I Utilisée pour parcourir les classes issues de la STL (standard
template library) : vector, map, queue, list, etc.
• Interface présente en Java dans le paquetage
java.util :
I Sert à parcourir les classes Collection, Map, HashTable, etc
Iterator (5/6)
Iterator (6/6)
Avantages
Découple les algorithmes de parcours des collections qui
contiennent les éléments.
Inconvénients
Mène parfois à une violation du principe d’encapsulation et expose
les structures et les algorithmes de parcours à des effets de bord
non sollicités.
Observer (1/6)
Dénominations
Observer (observateur), publish/suscribe
Contexte d’application
• Objectif :
I Observer l’état d’un objet dans un programme ;
I Notifier un changement dans un objet à un autre sans que les
deux ne se connaissent à priori.
• Utilisation :
I Réalisation d’un système distribué de réception et de
Observer (2/6)
Architecture de la solution
Subject
- observers : Observer[*]
Observer
+ getState()
+ notify() 1..1 0..* + registerObserver(obs : Observer)
+ unregisterObserver(obs : Observer)
+ notifyObserver()
notifyObservers() :
pour tout Observer
dans observers, appe-
ler notify()
Observer (3/6)
Entités participantes
• Subject
I Possède une interface pour attacher/détacher les observateurs ;
I Possède une liste privée d’observateurs.
• ConcreteSubject
I Implémente l’interface Subject, en particulier getState() ;
I L’objet observé en est une instance.
• Observer
I Définit une interface de mise à jour pour les observateurs ;
I Classe abstraite (à tout le moins l’opération notify).
• ConcreteObserver
I Le véritable observateur qui reçoit les évènements ;
I Surcharge l’opération notify.
Observer (4/6)
Exemples d’utilisation
• Utilisé à plusieurs reprises dans Java ;
I Dans les évènements envoyés par les éléments de l’interface
graphique (mécanisme des écouteurs) ;
I Sous la forme de la classe abstraite Observable et de
l’interface Observer (paquetage java.util).
• Framework Qt (interface graphiques) en C++ :
I Mécanisme signal/slot.
Observer (5/6)
AbstractButton
ActionListener # actionListener : ActionListener
+ addActionListener(al : ActionListener)
+ actionPerformed(e : ActionEvent) + removeActionListener(al : ActionListener)
+ fireActionPerformed(e : ActionEvent)
Réalise
MyActionListener
JButton
+ actionPerformed(e : ActionEvent)
Avantages
• Séparation entre Observateur et Objet d’observation ;
• Relation dynamique entre les deux éventuellement établie à
l’exécution ;
• Communication de masse (broadcast / multicast).
Observer (6/6)
Inconvénients
• Mises à jour intempestives ;
• Circuit des mises à jour parfois difficile à déboguer.
Strategy (1/5)
Dénominations
Strategy
Contexte d’application
• Objectif :
I Sélectionner à la volée (lors de l’exécution) des algorithmes à
appliquer sous certaines conditions ;
I Fournit des moyens de définir des familles d’algorithmes.
• Utilisation :
I Situation où il est nécessaire de permuter dynamiquement les
connaı̂tre.
Strategy (2/5)
Architecture de la solution
Context Strategy
1..1 1..1
+ concreteInterface() + algorithmInterface()
ConcreteStrategyA ConcreteStrategyB
concreteInterface() :
appelle algorithmInterface()
+ algorithmInterface() + algorithmInterface()
Strategy (3/5)
Entités participantes
• Strategy
I Interface définissant le comportement de la stratégie.
• ConcreteStrategy
I Implémente l’interface Strategy.
• Context
I Va utiliser l’interface Strategy.
Strategy (4/5)
Exemple d’utilisation
Border
JComponent
+ paintBorder(. . .)
- border : Border -border + getBorderInsets(. . .)
+ isBorderOpaque()
AbstractBorder
BevelBorder TitledBorder
CompoundBorder LineBorder
EmptyBorder EtchedBorder
SoftBevelBorder
MatteBorder
Strategy (5/5)
Avantages
• Dispense de l’utilisation de déclarations conditionnelles ;
• Fournit un choix d’implémentations pour un même
comportement ;
• Permet de faire de l’héritage dans des langages qui ne le
permettent pas (ex : C).
Inconvénients
• Les stratégies ne font pas forcément usage de tous les
éléments passés par le contexte ;
• Prolifération d’objets.
1 Introduction
2 Patrons comportementaux
3 Patrons structuraux
4 Patrons créationnels
5 Les anti-patrons
Adapter (1/6)
Dénominations
adapter (adaptateur), wrapper
Contexte d’application
• Objectif :
I Convertir l’interface d’une classe en l’interface attendue de la
part d’un client.
• Utilisation : (Moyennement élevée)
I Lorsque l’on veut normaliser l’utilisation d’anciennes classes
convient pas.
Adapter (2/6)
Architecture de la solution
Target
Client
+ request()
Adapter Adaptee
+ request() + specificRequest()
adaptee.specificRequest()
Adapter (3/6)
Entités participantes
• Target
IDéfinit l’interface ciblée par le client.
• Adapter
I Adapte l’interface d’Adaptee pour la rendre compatible avec
celle de Target.
• Adaptee
I Définit une interface existante qui nécessite adaptation.
• Client
I Collabore avec les objets en utilisant l’interface définie dans
Target.
Adapter (4/6)
Exemples d’utilisation
• Transformer une classe standard en Applet (Java) ;
• Rendre un objet distribuable via le réseau (Java – RMI) ;
• Classes anonymes (Java) :
p u b l i c c l a s s ButtonDemo {
p u b l i c ButtonDemo ( ) {
B u t t o n b u t t o n = new J B u t t o n ( " Press me " ) ;
button . addActionListener (
new A c t i o n L i s t e n e r ( ) {
public void actionPerformed ( ActionEvent e ) {
doOperation () ;
} } );
}
public void doOperation () { . . . }
}
Adapter (5/6)
ButtonDemo
ActionListener
+ ButtonDemo() : ButtonDemo
+ actionPerformed(e : ActionEvent)
+ doOperation()
+ actionPerformed(e : ActionEvent)
Adapter (6/6)
Avantage
Permet d’intégrer des objets existants dans de nouvelles structures
de classes sans être limité par leur interface.
Inconvénients
Surcoût en taille de code et en temps de calcul dû à l’appel des
opérations intermédiaires.
Composite (1/6)
Dénomination
Composite
Contexte d’application
• Objectif :
I Permet à un groupe d’objets d’être traités de la même manière
qu’un seul objet.
• Utilisation :
I Quand plusieurs objets sont utilisés de la même manière ;
I Pour représenter une hiérarchie d’objets ;
I Utile si la différenciation n’est pas un vrai besoin.
Composite (2/6)
Architecture de la solution
Component
+ operation()
Composite
Leaf
+ operation()
+ add()
+ operation() + remove()
+ getChildren()
Composite (3/6)
Entités participantes
• Component
I Est une abstraction de tous les composants ;
I Déclare l’interface des objets dans la composition ;
I Réalise le comportement commun par défaut ;
I Déclare une interface pour gérer les composants fils ;
I (Optionnel) Déclare une interface pour accéder aux parents.
• Leaf
I Représente une feuille de l’arbre (composant terminal).
• Composite
I Représente un composant composite (ayant des enfants) ;
I Réalise les opérations de manipulation des enfants ;
I Réalise les opérations de Component, généralement en les
Composite (4/6)
Exemples d’utilisation
• La hiérarchie des widgets graphiques en Java ;
• Description des noeuds de graphes de scènes dans
OpenInventor (C++).
Component
Composite (5/6)
SoNode
SoSwitch SoSeparator
Composite (6/6)
Avantages
• Facilite l’ajout de nouveaux composants ;
• Facilite l’écriture d’un client gérant ces objets ;
• Le client n’a pas connaissance du type (feuille ou composant
composite).
Inconvénient
• Rend la rectriction des types de composants composite
difficile.
1 Introduction
2 Patrons comportementaux
3 Patrons structuraux
4 Patrons créationnels
5 Les anti-patrons
Prototype (1/4)
Dénomination
Prototype
Contexte d’application
• Objectif :
I Spécifie le type d’objet à créer en utilisant un prototype
d’instance et créer de nouveaux objets en clonant le prototype.
• Utilisation : (moyenne)
I Utile si l’initialisation d’un objet est coûteuse en temps ;
I Ne requiert pas une classe, mais un objet.
Prototype (2/4)
Architecture de la solution
Prototype
Client
+ clone() : Prototype
ConcretePrototype1 ConcretePrototype2
Prototype (3/4)
Entités participantes
• Prototype
I Déclare une interface permettant de se cloner elle-même.
• ConcretePrototype
I Réalise l’interface Prototype afin de se cloner soi-même.
• Client
I Crée un nouvel objet par clonage via le prototype.
Exemple d’utilisation
La classe Object de Java
• Contient une méthode clone() ;
• À surcharger pour rendre n’importe quel type d’objet clonable.
Prototype (4/4)
Avantage
• Permet de créer des classes par clonage, ce qui peut s’avérer
plus rapide dans certains cas que la création par le biais d’un
constructeur classique.
Inconvénients
• Peu adapté dans le cas où l’on maintient des références à
d’autres objets ;
• Chaque prototype doit être instancié de manière classique une
fois, ce qui peut être un frein à la performance ;
• Requiert des objets à cloner une panoplie complète
d’accesseurs.
Singleton (1/4)
Dénomination
Singleton
Contexte d’application
• Objectif :
I S’assure qu’une classe possède une seule instance et fournit un
accès global à cette dernière.
• Utilisation : (moyennement élevée)
I Dans tous les cas où une seule instance de la classe est
nécessaire ;
I Pour contrôler l’accès à une ressource partagée (file
Singleton (2/4)
Architecture de la solution
-instance
Singleton
- instance : Singleton
- Singleton()
+ getInstance() : Singleton
Entité participante
• Singleton
I Emploie un constructeur à visibilité privée ;
I Possède un attribut de classe de type Singleton ;
I Donne accès à ce dernier via getInstance().
Singleton (3/4)
Exemples d’utilisation
Utilisé à trois reprises dans l’API Java :
• Classe Runtime donnant accès, pour l’application, à son
environnement d’exécution ;
• Classe Desktop pour lancer des actions liées au bureau
(interface graphique) dans lequel l’application est lancée ;
• Classe Toolkit qui lie les widgets Java et leur implémentation
native dans le système d’exploitation.
Singleton (4/4)
Avantages
• Facile à mettre en oeuvre ;
• Adapté pour certaines classes de test unitaire.
Inconvénients
• Le plus controversé des patrons de conception : souvent un
euphémisme pour les variables globales ;
• Doit être implémenté avec précaution dans un environnement
multi-threadé.
1 Introduction
2 Patrons comportementaux
3 Patrons structuraux
4 Patrons créationnels
5 Les anti-patrons
Les anti-patrons
Concept
• Extension naturelle de patrons de conception ;
• S’intéressent à la problématique du refactoring :
I Décrivent des synptômes (dysfonctionnements) ;
I Indiquent la recette à appliquer pour corriger l’application.
• Sont moins formalisés que les patrons de conception ;
• Sont au nombre d’une quarantaine.
Dénominations connues
Programmation spaghetti, code spaghetti, grosse boule de boue
(big ball of mud), etc.
Disney,
c La belle et le clochard
Robert
c Labay, Flickr
Solution de refactoring
1 Extraire les généralisations ;
Le Blob (1/3)
Dénominations connues
Blob, god object (objet divin)
Le Blob (2/3)
Contexte / symptôme
• Classe avec de nombreux attributs/opérations ;
• Classe de contrôle assistée de classe périphérique de données ;
• Peu de principes de la POO appliqués : en particulier violation
du principe Single responsability de SOLID.
Conséquences
• Perte des avantages liés à la POO ;
• Objet trop complexe à réutiliser ou tester ;
• Objet lourd en terme d’occupation mémoire.
Le Blob (3/3)
Solutions
• Identifier les responsabilités contenues dans la classe ;
• Décomposer le blob en classes traitant chacune un nombre
limité de responsabilités.
Origine de l’appelation
Culte réel ayant émergé en Mélanésie après la seconde guerre
mondiale.
Contexte / Symptômes
• Instructions inutiles / contre-productives dans le code source ;
• Faible expérience de l’équipe de développeurs.
Solutions
• Nettoyer le code, en retirer les portions inutiles ;
• Former les développeurs.
Conclusion
Synthèse
• Catalogue de solutions de conception : patrons de conception ;
• Catalogue de solutions de refactoring : les anti-patrons.
Critiques
• Patrons de conception : haut niveau d’abstraction ;
• Une réutilisation peu aisée ;
• Utiliser les patrons de conception à outrance est un
anti-patron.
References
Cunningham, W. (2013).
Anti patterns catalog.
http://c2.com/cgi/wiki?AntiPatternsCatalog.
Gamma, E., Helm, R., Johnson, R. et Vlissides, J. (1994).
Design patterns : elements of reusable object-oriented
software.
Pearson Education.