26
Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

Embed Size (px)

Citation preview

Page 1: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

Behavioral Design Patterns

The Observer Pattern

Roberto DemontisSylvain Giroux

Page 2: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain 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

Page 3: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

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é.

Page 4: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

Exemple I

Page 5: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

Exemple II

Layer

features : OMGraphicListobservers : Vector

setFeatures(OMGraphicList newFeatures)getFeatures() : OMgraphicListaddFeature(OMGraphic f)deleteFeature(OMGraphic f)

Page 6: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

Exemple IIIUn observateur --- plusieurs sources

Page 7: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

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);

}}…

}

Page 8: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

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

Page 9: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

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.

Page 10: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

Structure

Page 11: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

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)

Page 12: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

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

Page 13: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

CollaborationsaSubjectImpl :

SubjectImplaObserverImpl :

ObserverImplanotherObserverImpl :

ObserverImplaClient

2: notifyObservers

1: setState

3: update

4: getState

5: update

6: getState

Page 14: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

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.

Page 15: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

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.

Page 16: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

BénéficesSupport pour la communication “broadcast”

La source ne se préoccupe du nombre d’observateurs.

Page 17: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

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.

Page 18: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

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

Page 19: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

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();

}

Page 20: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

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é

Page 21: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

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

Page 22: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

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

Page 23: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

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

Page 24: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

Javapublic class Observable {... }

public interface Observer {

void update(Observable o, Object arg);

}

Page 25: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

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

Page 26: Behavioral Design Patterns The Observer Pattern Roberto Demontis Sylvain Giroux

The End