Patrons Conception
Patrons Conception
Patrons Conception
Quiz (à l’improviste)
Examen final
Plan du cours
Introduction générale
Patrons de création
Patrons de structure
Patrons de comportement
Motivation
"Concevoir un logiciel orienté-objet est difficile,
et concevoir un logiciel orienté-objet
réutilisable est encore plus difficile." - Erich
Gamma
2. Patrons de structure
Concernent la composition de classes et d'objets
Les patrons de structure aident à composer des groupes d’objets en des
structures plus larges
3. Patrons de comportement
Concernent l'interaction des classes et des objets
Les patrons de comportement aident à définir la communication entre
les objets du système et distribuer les responsabilités
Template des patrons de conception
Objectif
◦ Description de son utilité
Problème / Motivation
◦ Quand appliquer le patron de conception
◦ Un exemple illustrant quand le patron serait utile
Solution proposée
◦ Eléments impliqués & leurs relations
◦ Schémas conceptuels (e.g. diagrammes UML)
Conséquences
◦ Avantages et inconvénients du patron
Implémentation
◦ Implémenter un exemple en Java (votre mission!)
Patrons liés
◦ Autres patrons qui sont liés de manière proche à ce patron
Patrons de création
(Méthode) Fabrique / Factory Method :
◦ Déléguer la création d'un objet aux classes dérivées
Fabrique abstraite / Abstract Factory
◦ Créer une famille d'objets cohérents
Monteur / Builder
◦ Construire des objets complexes de manière
incrémentale
Prototype / Prototype
◦ Créer un objet par clonage d'une instance modèle
Singleton / Singleton
◦ Garantir une seule instance pour une classe
Fabrique (1)
Objectif :
Déléguer la création d'un objet aux classes dérivées
Problème :
◦ Création d’une commande adéquate pour chaque
catégorie de clients
◦ Deux catégories de clients :
ClientComptant : paie au comptant les articles commandés
création d’une instance de CommandeComptant
ClientCrédit : utilise un crédit
création d’une instance de CommandeCrédit
Fabrique (2)
• Solution proposée :
Fabrique (3)
• Structure générique :
Fabrique (4)
Commentaires :
◦ Méthode «créerCommande( ) : Commande » est une
méthode «fabrique» (nommée aussi «constructeur virtuel»)
Conséquences :
◦ Le processus de création peut être changé par héritage
◦ Le client demande au créateur de lui fournir une instance
◦ Le client ne connaît que l'interface de l'objet (e.g. Commande)
◦ Seul le créateur concret connaît la classe réelle de l'objet
new Arbre(Color.GREEN,
Color.BROWN, 8, 32, 8)
Prototype (2)
• Solution proposée
Chaque bouton contient un prototype à cloner
31
Singleton (2)
Structure générique
synchroniser getInstance()
class Singleton {
public static synchronized Singleton
getInstance() {……}
Exemple :
Pour les lycéens, le bouton ‘effacer tout’
prendra une allure différente :
Effacer tout
Façade / Facade
◦ Fournir une interface unifiée à l’ensemble des
interfaces des sous-systèmes
Poids-mouche / Flyweight
◦ Partager des instances pour éviter un nombre
trop important
Proxy / Proxy
◦ Fournir un substitut pour accéder à un objet
Adaptateur (1)
Objectif :
Convertir l’interface d’une classe existante en
une autre compatible avec l’application cliente
Problème
◦ Utiliser les fonctionnalités d’une bibliothèque
tierce mais l’interface n’est pas adaptée
Adaptateur(2)
• Solution proposée
Un serveur web du
système de vente de
véhicules crée et gère
des documents destinés
aux clients (html ou pdf).
Les documents Pdf sont
complexes à gérer. Un
composant du marché
ComposantPdf a été
choisi mais son interface
est incompatible avec
l’interface Document!
Adaptateur (3)
• Structure générique :
Adaptateur (4)
Conséquences
◦ Appelé aussi « wrapper »
◦ Permettre le dialogue entre classes incompatibles
◦ Indications d'utilisation :
• quand on veut utiliser une classe existante mais dont
l'interface ne coïncide pas avec celle attendue
nom des opérations
nombre de paramètres, types …
◦ Solution : Un objet de la classe adaptée est agrégé
dans l'adaptateur
Pont (1)
Objectif :
Séparer l'interface d'un composant de son
implémentation
Problème :
Un switch (composant)
admet deux
fonctionnalités on( ) et
off( ).
Il existe plusieurs
catégories de switchs
(interrupteur,
télécommande) qui
interagissent avec
différents appareils
(télévision, aspirateur…)
Pont (2)
• Solution proposée
Pont (3)
Structure générique
Pont (4)
Conséquences :
◦ Augmentation de l'extensibilité : deux hiérarchies
séparées: Composant et Implémenteur
◦ Chaque composant agrège une implémentation à
laquelle il délègue les appels aux méthodes
◦ Masquer totalement l'implémentation : plus
d'attributs déclarés dans le composant
Relations avec d'autres patrons
◦ Pont s'utilise en phase de conception, alors que
Adaptateur s'applique à des classes existantes
pour les connecter à posteriori
Composite (1)
Objectif :
Composer des objets en structures arborescentes
pour représenter des hiérarchies récursives
composant/composé
Problème
On veut rajouter
des propriétés à un
composant d’IHM
comme une
bordure, une barre
de défilement …
Décorateur (2)
• Solution proposée
Décorateur (3)
Utilisation : Stream en Java
Décorateur (4)
Structure générique
Décorateur (5)
Conséquences :
◦ Une alternative à l'héritage qui pourrait conduire à une
hiérarchie lourde :
Exemple de la zone de texte : 3 héritages sont nécessaires
(bordure, défilement, les deux)
Extension de la zone de texte : Extension des 3 classes
◦ Ajouter dynamiquement des fonctionnalités à un objet
sans affecter les autres instances de la même classe
◦ Mais comportement inattendu :
new DecorateurBordure(new DecorateurFond(zt)) ≠
new DecorateurFond(new DecorateurBordure(zt)) ?
Relations avec d'autres patrons
◦ Composite : utilisation «dégénérée» (1 seul enfant) du
patron composite
Façade (1)
Objectif :
Fournir une interface unifiée à l'ensemble des
interfaces des sous-systèmes. L’interface fournie
est de plus haut niveau et rend le système plus
facile à utiliser.
Problème :
◦ Bibliothèque complexe, avec beaucoup d'interfaces
◦ Complexité nécessaire pour des clients experts mais
inutile pour une majorité de clients
◦ On souhaite garder la puissance de la bibliothèque
tout en fournissant une interface simplifiée
Façade (2)
Solution proposée
Façade (3)
Structure générique
Façade (4)
Conséquences :
◦ La «façade» propose une interface simplifiée
◦ Elle connaît les détails du sous-système
◦ Le client envoie ses requêtes à la façade qui les
délègue aux composants du sous-système
◦ La liberté est laissée au client d'utiliser le jeu
d'interfaces bas niveau (le cas des experts)
Relations avec d'autres patrons
◦ Singleton : souvent, un seul objet façade par
programme
Poids-mouche (1)
Objectif :
Partager des instances pour éviter un nombre
trop important.
Problème :
◦ On souhaite gérer les options que l’acheteur peut
choisir quand il commande un nouveau véhicule
◦ Une option est caractérisée par un nom, une
description et un prix qui dépend du véhicule
◦ Un grand nombre d’options (objets de petite taille)
doit être géré alors que nombre d’entre elles
contiennent des données identiques
Poids-mouche (2)
Problème (suite)
Poids-mouche (3)
Solution proposée
◦ Séparation de l'état d'un objet en deux parties
Etat intrinsèque: indépendant du contexte stocké
dans l'objet
Etat extrinsèque: dépendant du contexte fourni en
paramètre par le client
Poids-mouche(4)
Solution proposée (suite) : Partage des options
Poids-mouche (5)
Solution proposée (suite) :
si (image = null)
alors image = new ImageReelle(nomFichier)
image.afficherImage()
Proxy (3)
Structure générique :
Proxy (4)
Conséquences :
◦ Le substitut, le «proxy», possède la même interface
que l'objet
◦ Lorsqu'il reçoit un message, il le transmet à l'objet
◦ Il peut effectuer un contrôle sur le message
Refuser de le retransmettre (proxy de protection)
Différer la retransmission
Altérer le message
Relations avec d’autres patrons :
◦ Décorateur: ajouter des fonctionnalités
◦ Proxy : contrôler les accès
Quiz 3
Une maison d’édition produit différents types
de publications (livres, articles, …).
Ces publications sont distribués sur différents
supports (CD, DVD, version papier…).
La classe parente
invoque les méthodes
des sous-classes. Ces
dernières n’effectuent
pas d’appel vers la
classe parente.
Principe de Hollywood
don’t call us, we will
call you!
Méthode patron (4)
Conséquences :
◦ Proposer plusieurs variantes d'un algorithme dont la
structure générale est inchangée
◦ Fixer clairement un comportement standard qui
devrait être partagé par toutes les sous-classes
◦ Mais éviter trop d'opérations primitives :
Redéfinition fastidieuse pour l'utilisateur
Implémentation :
◦ Appelée méthode socle et souvent déclarée final
(pour éviter sa redéfinition)
◦ Les opérations primitives (méthodes abstraites) sont
souvent déclarées protected (pour éviter de les
appeler directement)
Observateur (1)
Objectif :
◦ Construire une dépendance entre un objet
source (sujet) et des observateurs (abonnés).
◦ Quand le sujet change d’état :
tous ses observateurs sont informés
ils se mettent à jour
Problème :
◦ Affichage en temps réel à partir de données
provenant d’une station météo (température,
humidité, pression)
Observateur (2)
Solution proposée :
it =getIterator( )
tant que(it.estFini()=faux)
{it.suivant().affichage()}
Itérateur (3)
Structure générique :
Itérateur (4)
Conséquences :
◦ Abstraction de la structure de la collection
◦ Abstraction de la manière de parcourir
Un type d'itérateur par type de parcours
◦ Simplification de l’interface de la collection
◦ Plusieurs parcours simultanés de la collection
sont possibles
Relations avec d'autres patrons
◦ Composite : Itérateur souvent utilisé pour
parcourir l'arborescence
Etat (1)
Objectif :
Changer le comportement d'un objet en fonction
de son état
Problème :
Le cycle de vie d’une commande passe par 3 états:
◦ En cours de constitution : on peut ajouter, supprimer
un produit, valider la commande
◦ Validée (réglée par le client) : la commande peut
être livrée. On ne peut plus ajouter/supprimer un produit
◦ Livrée : la livraison a lieu ! On ne peut ni ajouter un
produit ni le supprimer
La classe Commande contient des méthodes dont le
comportement dépend de l’état de la commande
Etat (2)
Solution proposée :
etat.ajouterProduit(p)
Etat (3)
Structure générique :
Etat (4)
Conséquences :
◦ Etats représentés sous forme d'objets qui
possèdent la même interface
◦ Un objet agrège un état :
changement d'objet état changement de comportement
◦ Possibilité d’ajouter ou de retirer des états et des
transitions de manière simple
◦ Plus besoin de traitements conditionnels
Relations avec d’autres patrons :
◦ Poids-mouche : Les objets états peuvent être
partagés entre objets contextes
Stratégie (1)
Objectif :
Définir une famille d'algorithmes interchangeables pour
résoudre un même problème, et qui peuvent évoluer
indépendamment des applications qui les utilisent
Problème :
◦ Proposer une variété d’algorithmes pour un même
objectif
◦ Possibilité de changer dynamiquement l’algorithme
◦ Exemple de tri : tri par sélection, tri par insertion, tri
rapide …
Stratégie (2)
Solution proposée :
Stratégie (3)
Structure générique :
Stratégie (4)
Conséquences :
◦ Le choix d’un algorithme se fait dynamiquement en
fonction du contexte (choix de l’utilisateur,
performance …)
◦ Possibilité de changer dynamiquement l’algorithme
◦ Ajout d’un nouvel algorithme facile : une nouvelle
classe dérivée de Stratégie
◦ Mais léger surcoût du à l’augmentation du nombre
d’objets (surtout s’il faut changer souvent de
stratégie)
Relations avec d'autres patrons :
◦ Singleton : Les stratégies peuvent être des objets
uniques
Quiz 6
Une personne possède un cycle au long de sa vie
professionnelle. Elle est d’abord étudiante puis
intègre la vie active puis prend sa retraite. Elle ne
cotise pour sa retraite que lors de sa vie active.
Quel patron est le mieux adapté pour décrire
une personne au long de sa vie professionnelle?
Proposer un diagramme de classes. Introduire
les deux méthodes suivantes :
◦ getSituation ( ) : String qui renvoie l’état actuel de la
personne (étudiant, salarié, retraité)
◦ ajouterPoints(int n) : void qui ajoute des points de
retraites pour les personnes qui ont une vie active
Quiz 6 (suite)
Il s’agit maintenant de créer une interface
graphique qui affiche la personne ainsi que
son état professionnel. Chaque fois que les
données d’une personne sont changées
l’affichage dans l’interface graphique est mis à
jour automatiquement.
Quel patron de conception est le mieux
adapté pour concevoir cette interface?
Présenter le diagramme de classes complet
Quiz 7
Le catalogue d’une société de vente de véhicules
comprend la description de toutes les voitures
mises en vente.
On souhaite laisser la liberté à l’utilisateur pour
choisir l’algorithme d’affichage du catalogue qui
lui convient (affichage vertical, horizontal, sous
forme de grille, etc)
Quel patron est le mieux adapté pour
résoudre ce problème?
Proposer un diagramme de classes en utilisant
ce patron