Upload
aubin-vannier
View
113
Download
1
Tags:
Embed Size (px)
Citation preview
Behavioral Design Patterns
The Observer Pattern
Roberto DemontisSylvain Giroux
IntentionDéfinir une dépendance de “1” à “n” entre des objets
de telle sorte que
lorsque l’état d’un objet change,
tous ses dépendants sont informés et mis-à-jour automatiquement
MotivationUn effet de bord fréquent de la partition d’un système en une collection de classes coopérantes est la nécessité de maintenir la consistence entre les objets reliés entre eux.
On ne veut pas obtenir la consistance en liant étroitement les classes, parce que cela aurait comme effet de réduire leur réutilisabilité.
Exemple I
Exemple II
Layer
features : OMGraphicListobservers : Vector
setFeatures(OMGraphicList newFeatures)getFeatures() : OMgraphicListaddFeature(OMGraphic f)deleteFeature(OMGraphic f)
Exemple IIIUn observateur --- plusieurs sources
Exemple IVpublic static void main(java.lang.String[] args) {…
for (Iterator lesCours=Cours.getInstances().iterator(); lesCours.hasNext();){
Cours unCours = (Cours)lesCours.next();for (Iterator
lesLocaux=Local.getInstances().iterator();lesLocaux.hasNext();)
{Local unLocal = (Local)lesLocaux.next();unLocal.addVetoableChangeListener(unCours);unLocal.addPropertyChangeListener(unCours);
}}…
}
FonctionnementLe pattern “Observer” décrit
comment établir les relations entre les objets dépendants.
Les objets-clés sont la source
Peut avoir n’importe quel nombre d’observateurs dépendantsTous les observateurs sont informés lorsque l’état de la source change
l’observateur.Chaque observateur demande à la source son état afin de se synchroniser
Quand l’appliquerLorsqu’une abstraction possède deux aspects dont l’un dépend de l’autre.
L’encapsulation de ces aspects dans des objets séparés permet de les varier et de les réutiliser indépendemment. Exemple : Modèle-Vue-Contrôleur
Lorsqu’une modification à un objet exige la modification des autres, et que l’on ne sait pas a priori combien d’objets devront être modifiés.
Exemple : TP sur la réservation des locaux
Lorsqu’un objet devrait être capable d’informer les autres objets sans faire d’hypothèses sur ce que sont ces objets,
on ne veut pas que les objets soient étroitement liés.
Structure
InterfacesSources
Définir une interface pour les objets qui doivent “notifier” leur changement d’état
En Java, par conventionAdd/remove/PropertyChangeListener
ObservateursDéfinir une interface pour les objets qui seront informés des changements d’états
PropertyChangeListener void propertyChange( PropertyChangeEvent e)
ImplementationImplémentation des Sources
Mémorise son état afin que les observateurs puissent le lire. Notifie les objets observateurs des changements de leur état en implémentant une méthode notifier\fireEventGère les références aux observateurs intéressés add\remove___Listener
Implémentation des ObservateursConserver une référence à l’objet source Implementer la méthode de notification
Par exemple, update
CollaborationsaSubjectImpl :
SubjectImplaObserverImpl :
ObserverImplanotherObserverImpl :
ObserverImplaClient
2: notifyObservers
1: setState
3: update
4: getState
5: update
6: getState
BénéficesUtilisation indépendante des sources et des observateurs.
On peut réutiliser les sources sans réutiliser les observateurs et vice-versa.
On peut ajouter des observateurs sans modifier la source et les autres observateurs.
BénéficesCouplage abstrait entre les sources et les observateurs.
La source ne s’intéresse pas à la classe des observateurs
Une source et un observateur peuvent appartenir à des niveaux différents d’un système.
BénéficesSupport pour la communication “broadcast”
La source ne se préoccupe du nombre d’observateurs.
DésavantagesMises-à-jour imprévues.
Parce que les observateurs n’ont aucune connaissance de la présence des autres, ils ne peuvent connaître le coût réel total d’une modification de la source.
Une opération apparemment anodine sur la source peut entraîner une cascade de mises-à-jour des observateurs et des objets qui en dépendent.
Choix liés à l’implementation I
Associations sources-observateursDans la sourceHashtable sources-observateurs
Par exemple en Smalltalk dans la classe Object
Observation de plus d’une sourceQui a déclenché la notification ?
Solution : adapteurs pour démultiplexer les sources
Qui déclenche la notification ?La source après une modification de son étatLes clients
Pour éviter les mises-à-jour intermédiaires
Choix liés à l’implémentation II
Références en suspens à des sources détruites
S’assurer que l’état de la source est consistent avant la notification
Par exemple, si la notification est faite avant de faire le changement d’état, alors les observateurs qui interrogeront la source ne récupèreront pas la bonne valeur
Solution possible : design pattern Template Method Void cut( TextRange r){ Replace(); \\ à redéfinir dans la sous-classenotify();
}
Choix liés à l’implémentation III
Éviter les protocoles de mise-à jour spécifiques
Modèle Push source envoie des informations détaillées que l’observateur le veuille ou nonsuppose que la source connaît l’information dont la source a besoin
Peut rendre les observateurs moins réutilisables
Modèle PullL’observateur vient chercher l’information dont il a besoinEmphase sur l’ignorance des observateurs par la sourcePeut être inefficace car les observateurs doivent identifier ce qui a changé
Choix liés à l’implémentation IV
Spécifier explicitement les modifications d’intérêt pour l’observateur
Améliore l’efficacitéaddPropertyChangeListener(“texte”, aListener);
Fusion de classes de sources et d’observateurs Objets qui sont à la fois source et observateursDans les langages qui n’ont pas l’héritage multiple, on combine souvent les interfaces de sources et d’observateurs dans une même classe.
En Smalltalk , les interfaces des sources et des observateurs sont combinées dans la classe Object, ce qui les rend disponibles à toutes les classes
Choix liés à l’implémentation V
Encapsuler les sémantiques complexes de mises-à-jour
Par exemple si une opération implique plusieurs sources interdépendentes, il faut s’assurer que les observateurs sont informés après la modification de toutes les sources pour éviter de notifier les observateurs plus d’une fois
Gestionnaire de modifications : ChangeManagerTable de correspondance entre une source et ses observateursStratégie spécifique de mise-à-jourÀ la demande de la source met à jour les observateurs dépendants
Gestionnaire de modifications
DP Mediator : définit un objet qui encapsule la manière dont plusieurs objets interagissent entre eux
DP Singleton car il n’y a en général qu’un seul ChangeManager
Javapublic class Observable {... }
public interface Observer {
void update(Observable o, Object arg);
}
BibliographieDesign Patterns; Elements of Reusable Object-Oriented Software, E. Gamma, R. Helm, R. Johnson, J. Vlissides pag. 293-304
Java Design Patterns 101 ibm.com\developersWorks
The End