Observateur : Différence entre versions
(3 révisions intermédiaires par le même utilisateur non affichées) | |||
Ligne 14 : | Ligne 14 : | ||
=== Code Java === | === Code Java === | ||
− | [[Fichier:ObserverCodeUML.png| | + | [[Fichier:ObserverCodeUML.png|1300px]] |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | === Texte explicatif du code === | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | Exemple : Affichage de l’heure | |
− | + | Dans notre exemple, on veut gérer l’heure à partir d’une classe et l’affichée de deux manière différente à partir de deux autres classes. | |
− | + | On crée donc deux interface : Observer et Observable. Les deux Observer concret (AffichageENG et AffichageFR) implémentent l'interface Observer tandis que la classe concrète (HeurePerso) implémente l'interface Observable. On créer également un point d’entré avec la classe. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | A chaque modification de notre objet observable, il y aura un comportement différent pour chaque observer contenu dans cette liste. Ici, dès que l'on fait appel à la fonction setHeure() ou setMinute(), cela va faire appel à la fonction notifyObserver() qui, pour chaque Observer dans la liste, appelle update(). Cette fonction est présente dans les classe qui implémente l'interface Observable. Dans notre exemple, elle est chargée d'afficher le changement d'heure qui a eu lieu mais cette fonction peut aussi modifier, ou renvoyer, une valeur selon les cas d'utilisation. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
<nowiki> | <nowiki> | ||
− | + | HeurePerso time = new HeurePerso(); | |
− | + | AffichageFR obsFR = new AffichageFR(); | |
− | + | AffichageENG obsENG = new AffichageENG(); | |
− | + | time.addObserver(obsFR); | |
− | + | time.addObserver(obsENG); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | time.setHeure(11); | |
+ | time.setMinute(05); | ||
+ | time.setHeure(15); | ||
+ | </nowiki> | ||
− | + | Dans notre application, on crée un observable que l'on nomme « time ». On crée ensuite deux observer, « obsFR » et « obsENG ». On ajoute les deux observer dans la liste de l’objet « time ». Afin on modifie l’heure et les minutes. Cela a pour effet d’affiché la nouvelle heure en français et en anglais. | |
+ | Résulat : | ||
+ | <nowiki> | ||
+ | 11:0 | ||
+ | 11.0AM | ||
+ | 11:5 | ||
+ | 11.5AM | ||
+ | 15:5 | ||
+ | 3.5PM</nowiki> | ||
+ | Le résultat est affiché sans qu’on le demande. | ||
− | + | Ce design pattern permet de changer le comportement des obersavateurs sans toucher à la classe observable. La solution consiste donc à laisser la charge à la classe HeurePerso d’informer sa classe d’affichage de ses changements de valeurs. Cependant la classe HeurePerso doit pouvoir informer plusieurs classes d’affichage et cela en évitant de lier fortement les classes entre elles. C’est à dire qu’une modification des classes d’affichage ne doit pas engendrer de modification dans la classe métier et vice versa. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | Ce design pattern permet de changer le comportement des obersavateurs sans toucher à la classe observable. | + | |
− | La solution consiste donc à laisser la charge à la classe HeurePerso d’informer sa classe d’affichage de ses changements de valeurs. Cependant la classe HeurePerso doit pouvoir informer plusieurs classes d’affichage et cela en évitant de lier fortement les classes entre elles. C’est à dire qu’une modification des classes d’affichage ne doit pas engendrer de modification dans la classe métier et vice versa. | + | |
== Désavantages == | == Désavantages == | ||
Chaque observateur souhaitant être informé d’un changement d’état doit se trouver dans le tableau d’observer de l’observable. Pour cela il faut les ajouter un par un dans ce tableau. | Chaque observateur souhaitant être informé d’un changement d’état doit se trouver dans le tableau d’observer de l’observable. Pour cela il faut les ajouter un par un dans ce tableau. |
Version actuelle en date du 12 octobre 2018 à 10:37
Le pattern Observateur (en anglais Observer) définit une relation entre objets de type un-à-plusieurs, de façon que, si un objet change d’état, tous ceux qui en dépendent en soient informés et mis à jour automatiquement.
Sommaire
Pourquoi l’utiliser ?
Supposons une classe gérant des données GPS, et plusieurs classes responsables de l’affichage de ces données. On peut imaginer une méthode dans les classes d’affichages pour récupérer la position GPS, mais à quelle fréquence doivent-elles demander la position ? Chaque seconde ? Chaque milliseconde ? Avec cette solution, on ne peut pas être sûr de l’exactitude des données. La solution est d’utiliser le design pattern Observer, qui permet d’informer les classes d’affichages automatiquement lorsque la position GPS est modifiée.
Diagramme UML
Exemple Java
Code Java
Texte explicatif du code
Exemple : Affichage de l’heure
Dans notre exemple, on veut gérer l’heure à partir d’une classe et l’affichée de deux manière différente à partir de deux autres classes.
On crée donc deux interface : Observer et Observable. Les deux Observer concret (AffichageENG et AffichageFR) implémentent l'interface Observer tandis que la classe concrète (HeurePerso) implémente l'interface Observable. On créer également un point d’entré avec la classe.
A chaque modification de notre objet observable, il y aura un comportement différent pour chaque observer contenu dans cette liste. Ici, dès que l'on fait appel à la fonction setHeure() ou setMinute(), cela va faire appel à la fonction notifyObserver() qui, pour chaque Observer dans la liste, appelle update(). Cette fonction est présente dans les classe qui implémente l'interface Observable. Dans notre exemple, elle est chargée d'afficher le changement d'heure qui a eu lieu mais cette fonction peut aussi modifier, ou renvoyer, une valeur selon les cas d'utilisation.
HeurePerso time = new HeurePerso(); AffichageFR obsFR = new AffichageFR(); AffichageENG obsENG = new AffichageENG(); time.addObserver(obsFR); time.addObserver(obsENG); time.setHeure(11); time.setMinute(05); time.setHeure(15);
Dans notre application, on crée un observable que l'on nomme « time ». On crée ensuite deux observer, « obsFR » et « obsENG ». On ajoute les deux observer dans la liste de l’objet « time ». Afin on modifie l’heure et les minutes. Cela a pour effet d’affiché la nouvelle heure en français et en anglais.
Résulat :
11:0 11.0AM 11:5 11.5AM 15:5 3.5PM
Le résultat est affiché sans qu’on le demande.
Ce design pattern permet de changer le comportement des obersavateurs sans toucher à la classe observable. La solution consiste donc à laisser la charge à la classe HeurePerso d’informer sa classe d’affichage de ses changements de valeurs. Cependant la classe HeurePerso doit pouvoir informer plusieurs classes d’affichage et cela en évitant de lier fortement les classes entre elles. C’est à dire qu’une modification des classes d’affichage ne doit pas engendrer de modification dans la classe métier et vice versa.
Désavantages
Chaque observateur souhaitant être informé d’un changement d’état doit se trouver dans le tableau d’observer de l’observable. Pour cela il faut les ajouter un par un dans ce tableau.