Chapitre 4
PATRONS DE COMPORTEMENT
 
 
Précédent Suivant
 
Patrons de comportement
Patrons de comportement (1/4)
* Abstraction du comportement
* Structure algorithmique
* Affectation de responsabilités aux objets
* Communication entre objets
* Niveau classe
* Utilisation de l'héritage
* Répartition du comportement
* Niveau objet
* Utilisation de la composition
* Coopération d'objets pour effectuer une tâche
Patrons de comportement (2/4)
* Permet l'assemblage de composants
* Pour obtenir une fonctionnalité plus élaborée
* Algorithmes vus comme des objets
* Comment les composants communiquent ?
* Niveau de connaissance des pairs
* Références explicites les uns envers les autres
* Perte des références, utilisation d'un intermédiaire
* Propagation d'un message
* Délégation
* Transmission
* Messages vus comme des objets
Patrons de comportement (3/4)
* Chaîne de responsabilité / Chain of Responsibility
* Transmettre une requête de proche en proche jusqu'à traitement
* Commande / Command
* Encapsuler une action dans un objet
* Interpréteur / Interpreter
* Représenter la grammaire d'un langage
* Itérateur / Iterator
* Fournir un accès séquentiel aux éléments d'un agrégat
* Médiateur / Mediator
* Encapsuler la manière d'interagir d'un groupe d'objets
Patrons de comportement (4/4)
* Mémento / Memento
* Capturer et externaliser l'état d'un objet
* Observateur / Observer
* Synchroniser plusieurs objets sur l'état d'un autre objet
* Etat / State
* Changer le comportement d'un objet en fonction de son état
* Stratégie / Strategy
* Rendre les algorithmes d'une même famille interchangeables
* Méthode patron (Patron de méthode) / Template Method
* Spécialiser un algorithme sans changer sa structure générale
* Visiteur / Visitor
* Représenter une opération à appliquer sur un ensemble d'objets
Chaîne de responsabilité (1/4)
* "Chain of Responsibility"
* Objectif
* Transmettre une requête de proche en proche jusqu'à traitement
* Eviter le couplage entre l'émetteur et les receveurs potentiels
* Principe
* La requête est transmise de receveur en receveur
* Jusqu'à ce qu'elle soit traitée
* Les receveurs ont la même interface pour répondre à la requête
* Référence sur un successeur pour former une chaîne
* Le client transmet une requête au premier de la chaîne
* Motivation
* Action contextuelle: demande d'aide dans une application
* Requête reçue par le composant le plus bas
* Requête remontée jusqu'à ce qu'un composant la traite
Chaîne de responsabilité (2/4)
Chaîne de responsabilité (3/4)
Chaîne de responsabilité (4/4)
* Intérêts
* Couplage réduit entre l'émetteur et les receveurs potentiels
* Pas de connaissance explicite de tous les receveurs
* Evite que l'émetteur maintienne une liste de candidats
* Modification dynamique de la chaîne des responsables
* A tout moment, un objet peut être ajouté ou retiré
* Mais une requête peut ne pas être satisfaite
* Relations avec d'autres patrons
* Composite
* Avec une représentation sous forme arborescente
* La chaîne de responsabilité peut être induite par la hiérarchie
* Le parent agit alors comme le successeur dans la chaîne
Commande / Command (1/4)
* Objectif
* Encapsuler une action dans un objet
* Permet l'abstraction de l'action
* Possibilité de file d'attente, annulation...
* Principe
* Une interface modélise les actions
* Les objets déclencheurs agrègent une action
* Déclencheur activé ==> exécution de l'action
* L'action connaît toutes les informations pour l'exécution
* Procédure à exécuter
* Quels sont les objets concernés
* Motivation
* Associer des actions aux boutons d'une interface graphique
* Les boutons n'ont pas de lien direct avec le code métier
Commande / Command (2/4)
Commande / Command (3/4)
Commande / Command (4/4)
* Appelé aussi "action", "transaction"
* Intérêts
* Découplage entre déclencheur et receveur
* Ajout dynamique de nouvelles commandes
* Possibilité de commandes agrégées (macrocommandes)
* Relations avec d'autres patrons
* Composite
* Utilisé pour concevoir une macrocommande
* Mémento
* Mémorisation d'informations pour un processus d'annulation
Itérateur / Iterator (1/4)
* Objectif
* Fournir un accès séquentiel aux éléments d'un agrégat
* Sans exposer sa représentation interne
* Principe
* Itérateur = "pointeur" sur un élément d'un agrégat
* L'agrégat fournit des itérateurs
* Tous implémentent la même interface (quelque soit l'agrégat)
* Le client ne manipule que l'itérateur
* Il n'a pas forcément connaissance de l'agrégat
* L'itérateur connaît la structure interne de l'agrégat
* Il définit la manière de parcourir les éléments
* Motivation
* Parcourir les éléments d'un conteneur
Itérateur / Iterator (2/4)
* L'itérateur fournit généralement 4 services
* Positionnement sur le 1er élément du parcours
* Déplacement à l'élément suivant
* Accès à l'élément courant
* Test de fin de parcours
* L'accès à l'élément peut être contrôlé
* Exemple: itérateur en lecture simple
* L'itérateur possède un état interne
* Référence directe à l'élément
* Référence à l'agrégat + position
* Besoin d'accéder à l'implémentation de l'agrégat
* Classe embarquée
* Classe amie
Itérateur / Iterator (3/4)
Itérateur / Iterator (4/4)
* Appelé aussi "curseur"
* Intérêts
* Abstraction de la structure de l'agrégat
* Seul l'itérateur est connu
* Abstraction de la manière de parcourir
* Un type d'itérateur par type de parcours
* Evite de polluer l'interface de l'agrégat
* Parcours simultanés possibles
* Relations avec d'autres patrons
* Composite
* Itérateur souvent utilisé pour parcourir l'arborescence
Médiateur / Mediator (1/4)
* Objectif
* Encapsuler la manière d'interagir d'un groupe d'objets
* Pas de référence explicite entre les objets
* Principe
* Lorsqu'un objet a besoin d'un service
* Il s'adresse à un objet central: le "médiateur"
* Le médiateur comprend les requêtes
* Il connaît les objets du système
* Il sait à qui déléguer les requêtes
* Motivation
* Communication d'objets dans une interface graphique
* Beaucoup de messages liés aux événements
* Il n'est pas nécessaire que chacun connaisse tous les autres
Médiateur / Mediator (2/4)
Médiateur / Mediator (3/4)
Médiateur / Mediator (4/4)
* Intérêts
* Abstraction du mécanisme d'interaction
* Découplage des objets
* Possibilité de modifier le mécanisme indépendamment
* Contrôle centralisé
* Evite la répartition sur plusieurs objets
* Facilite l'extension: une classe à étendre
* Relations avec d'autres patrons
* Observateur
* Moyen de communication avec le médiateur
Mémento / Memento (1/3)
* Objectif
* Capturer et externaliser l'état d'un objet
* Sans violer l'encapsulation
* Permettre sa restauration ultérieure
* Principe
* "Mémento" = objet représentant l'état interne d'un autre objet
* Un objet est le seul "initiateur" de ses mémentos
* Lui seul peut accéder aux données du mémento par la suite
* Motivation
* Mécanisme d'annulation ("undo") parfois complexe
* Nécessité de mémoriser l'état d'un objet pour le restituer plus tard
Mémento / Memento (2/3)
Mémento / Memento (3/3)
* Appelé aussi "token"
* Intérêts
* Préserve l'encapsulation de l'initiateur
* Aucun objet extérieur n'accède à son état
* Peu d'impact sur le code de l'initiateur
* Seules les méthodes de création et restauration sont rajoutées
* La gestion des mémentos est faite à l'extérieur
* Difficile de garantir l'accès exclusif de l'initiateur
* Dépend du langage
* C++: méthodes protégées et relation d'amitié
* Relations avec d'autres patrons
* Commande
* Utilisation conjointe pour le mécanisme d'annulation
* Itérateur
* Mémento = état d'une itération
Observateur / Observer (1/4)
* Objectif
* Synchroniser plusieurs objets sur l'état d'un autre objet
* Quand l'état de l'objet change
* Les objets dépendants sont informés
* Ils se mettent à jour
* Principe
* Des objets "observateurs" s'enregistrent auprès d'un "sujet"
* Le sujet maintient donc une liste de ses observateurs
* Changement de l'état du sujet ==> Notification aux observateurs
* Une méthode spécifique des observateurs est invoquée
* Tous les observateurs doivent donc implémenter la même interface
* Motivation
* Capter des événements dans une interface utilisateur
Observateur / Observer (2/4)
Observateur / Observer (3/4)
Observateur / Observer (4/4)
* Appelé aussi "dependents", "publish-subscribe" ou "listener"
* Intérêts
* Evite un couplage fort entre le sujet et les observateurs
* Le type concret des observateurs n'est pas connu du sujet
* Les observateurs sont passifs
* Pas besoin d'interroger le sujet en permanence
* Informés quand le sujet change d'état
* Mais attention au coût de modification de l'état du sujet
* Implémentation
* Stockage de l'association observateur-sujet
* Interne, chaque sujet maintient une liste d'observateurs
* Externe, dans un conteneur associatif
* Un observateur peut avoir plusieurs sujets
* La méthode "mettreAJour" doit recevoir le sujet
* Relations avec d'autres patrons
* Modèle-Vue-Contrôleur (MVC)
* Modèle = sujet
* Vue = observateur
Etat / State (1/4)
* Objectif
* Changer le comportement d'un objet en fonction de son état
* Changement d'état équivalent à un changement de classe
* Principe
* Etats représentés sous forme d'objets
* Ils possèdent la même interface
* Chaque implémentation ==> un état différent
* Un objet agrège un état
* Changement de comportement ==> changement d'objet état
* Motivation
* Réponses différentes suivant l'état d'une connexion réseau
* Etats: établie, en attente, fermée...
Etat / State (2/4)
Etat / State (3/4)
Etat / State (4/4)
* Appelé aussi "objects for states"
* Intérêts
* Evite des tests de comportement suivant l'état
* Les comportements spécifiques sont localisés
* Donc faciles à maintenir
* Les transitions d'état sont explicites
* Mais qui change l'état de l'objet ?
* L'objet lui-même ou son objet état ?
* Relations avec d'autres patrons
* Poids-mouche
* Les objets états peuvent être partagés entre objets
* Singleton
* Les objets états peuvent être des singletons
Stratégie / Strategy (1/5)
* Objectif
* Rendre les algorithmes d'une même famille interchangeables
* Principe
* Les algorithmes ("stratégies") sont modélisés par des classes
* Une méthode représente le point d'entrée
* Une classe abstraite définit une famille d'algorithmes
* Nouvel algorithme = héritage et redéfinition du point d'entrée
* Un objet "contexte" agrège un algorithme
* Sans connaître sa classe concrète
* Le polymorphisme rend les algorithmes interchangeables
* Motivation
* Proposer une variété d'algorithmes pour un même objectif
* Possibilité de changer dynamiquement l'algorithme
Stratégie / Strategy (2/5)
Stratégie / Strategy (3/5)
Stratégie / Strategy (4/5)
* Appelé aussi "policy"
* Intérêts
* Abstraction de la stratégie
* Interchangeable dynamiquement
* Nouvelle stratégie ==> Aucun impact sur le contexte
* La stratégie est dissociée du contexte
* Evite des tests dans le contexte pour sélectionner la stratégie
* Contenu classique d'une classe stratégie/algorithme
* Un point d'entrée
* Méthode publique appelée pour exécuter l'algorithme
* Des sous-algorithmes
* Méthodes protégées utilisées par le point d'entrée
* Des paramètres
* Mémorisés dans des attributs
* Constructeurs et accesseurs nécessaires pour l'initialisation
* Relations avec d'autres patrons
* Singleton
* Les stratégies peuvent être des objets uniques
Stratégie / Strategy (5/5)
* Utilisation de la stratégie pour un algorithme "à trous"
Généricité dans les patrons de conception
* Stratégie, version générique
* Gain: pas de virtualité au niveau des méthodes de la stratégie
Méthode patron / Template Method (1/6)
* Très souvent appelé "patron de méthode"
* Mauvaise traduction ?
* Objectif
* Spécialiser un algorithme sans changer sa structure générale
* Principe
* Définir le squelette d'un algorithme dans une classe
* De la même manière que la stratégie
* Délocaliser des parties dans des méthodes virtuelles
* Par héritage, ces parties pourront être redéfinies
* Motivation
* Proposer plusieurs variantes d'un algorithme
* Où la structure générale de l'algorithme est inchangée
Méthode patron / Template Method (2/6)
Méthode patron / Template Method (3/6)
Méthode patron / Template Method (4/6)
* Intérêts
* Abstraction de parties d'un algorithme
* Conserve la structure générale de l'algorithme
* Rôle très important dans la réutilisabilité
* Evite un détournement du rôle d'une classe
* Guide / facilite la spécialisation de la classe
* Mais éviter trop d'opérations primitives
* Appelées trop souvent ==> Surcoût lié à la virtualité
* Trop de méthodes ==> Redéfinition fastidieuse pour l'utilisateur
* Utilisé pour la redéfinition "par complément"
* Objectif: redéfinir pour compléter une méthode
* Problème: il ne faut pas oublier d'appeler la version mère
* Solution: utiliser une méthode patron
Méthode patron / Template Method (5/6)
* Redéfinition par complément
* Approche classique
class Mere {
public void m() { /* Quelque chose */ }
}
class Fille extends Mere {
public void m() { super.m(); /* Autre chose */ }
}
* Approche avec méthode patron
abstract class Mere {
public void m() { /* Quelque chose */ autreChose(); }
protected abstract void autreChose();
}
class Fille extends Mere {
protected void autreChose() { /* Autre chose */ }
}
Méthode patron / Template Method (6/6)
* Implémentation
* Opérations primitives déclarées en protégé
* Impossible de les appeler directement
* Accessibles par les sous-classes, donc redéfinissables
* Pour imposer la redéfinition, déclarer ces méthodes abstraites
* Relations avec d'autres patrons
* Stratégie
* Peuvent être conjoints
* Stratégie: composition pour faire varier l'algorithme entier
* Méthode patron: héritage pour faire varier des parties
* (Méthode) Fabrique
* Utilise une méthode patron pour la création de produits
* Visiteur
* Similaires, mais le visiteur utilise la composition
* Les parties sont remplacées dynamiquement
Visiteur / Visitor (1/4)
* Objectif
* Représenter une opération à appliquer sur un ensemble d'éléments
* Définir une nouvelle opération sans modifier la classe des éléments
* Principe
* L'opération est modélisée par un objet, le "visiteur"
* Une classe, extensible, représente l'opération
* Les éléments doivent "accepter" un visiteur
* Une méthode doit recevoir le visiteur
* Et appliquer l'opération associée sur l'élément
* Une procédure de parcours applique l'opération aux éléments
* Elle reçoit le visiteur
* Et le transmet à chacun des éléments
* Motivation
* Appliquer des opérations différentes sur un ensemble d'objets
* Mais le processus de parcours est toujours le même
Visiteur / Visitor (2/4)
Visiteur / Visitor (3/4)
Visiteur / Visitor (4/4)
* Intérêts
* Propose plusieurs traitements sur les éléments
* Sans alourdir l'interface de la structure
* Sans alourdir l'interface des éléments
* Facilite l'ajout de nouveaux traitements
* Il suffit de créer un nouveau visiteur
* Mais difficile d'ajouter un nouvel élément
* Il faut ajouter une méthode dans chaque visiteur
* Relations avec d'autres patrons
* Composite
* Visiteur utilisé pour appliquer une opération sur l'arborescence
* Méthode patron
* Visiteur peut être utilisé pour spécialiser des parties d'un algorithme
* Similaires, mais la méthode patron utilise l'héritage