XRF
Patrons de conception/Observateur
Le patron de conception observateur/observable est utilisé en programmation pour envoyer un signal à des modules qui jouent le rôle d'observateur.
En cas de notification, les observateurs effectuent alors l'action adéquate en fonction des informations qui parviennent depuis les modules qu'ils observent (les "observables").
Dans ce patron de conception, l'objet observé maintient une liste d'observateurs et les notifient automatiquement de tout changement d'état, généralement en appelant une de leur méthode.
Utilité.
La notion d'observateur/observable permet de découpler des modules de façon à réduire les dépendances aux seuls phénomènes observés.
Utilisation.
Dès que l'on a besoin de gérer des événements, quand une classe déclenche l'exécution d'une ou plusieurs autres.
Dans une interface graphique utilisant MVC (Modèle-Vue-Contrôleur), le patron Observateur est utilisé pour associer Modèle et Vue.
Par exemple, en Java Swing, le modèle est censé notifier la vue de toute modification en utilisant codice_1.
Les Java beans sont les observés, les éléments de la vue sont les observateurs.
Tout changement dans le modèle est alors visible sur l'interface graphique.
Illustration.
Prenons comme exemple une classe qui produit des signaux (données observables), visualisés à travers des panneaux (observateurs) d'une interface graphique.
On souhaite que la mise à jour d'un signal modifie le panneau qui l'affiche.
Afin d'éviter l'utilisation de threads ou encore d'inclure la notion de panneau dans les signaux il suffit d'utiliser le patron de conception observateur/observable.
Le principe est que chaque classe observable contienne une liste d'observateurs, ainsi à l'aide d'une méthode de notification l'ensemble des observateurs sont prévenus.
La classe observée hérite de "Observable" qui gère la liste des observateurs.
La classe Observateur est quant à elle purement abstraite, la fonction de mise à jour ne pouvant être définie que par une classe spécialisée.
Exemples.
Java.
L'exemple ci-dessous montre comment utiliser l'API du langage Java qui propose des interfaces et des objets abstraits liées à ce patron de conception.
class Signal extends Observable
 void setData(byte[] lbData)
 setChanged(); // Positionne son indicateur de changement
 notifyObservers(); // (1) notification
class JPanelSignal extends JPanel implements Observer
 void init(Signal lSigAObserver)
 lSigAObserver.addObserver(this); // (2) ajout d'observeur

void update(Observable observable, Object objectConcerne)
 repaint(); // (3) traitement de l'observation
C++.
Dans cet exemple en C++, on veut afficher les événements qui se produisent dans une classe Exemple.
using namespace std;
class IObserver
public:
 virtual void update(string data) = 0;
class Observable
private:
 list<IObserver*> list_observers;
public:
 void notify(string data)
 // Notifier tout les observers
 for ( list<IObserver*>::iterator it = this->list_observers.begin() ;
 it != this->list_observers.end() ;
 ++it )
 (*it)->update(data);
 void addObserver(IObserver* observer)
 // Ajouter un observateur à la liste
 this->list_observers.push_back(observer);
};
class Display : public IObserver
 void update(string data)
 cout « "Événement : " « data « endl;
};
class Exemple : public Observable
public:
 void message(string message)
 // Lancer un événement lors de la réception d'un message
 this->notify(message);
};
int main()
 Display display;
 Exemple exemple;
 // On veut que "Display" soit prévenu à chaque réception d'un message dans "Exemple"
 exemple.addObserver(&display);
 // On envoie un message a Exemple
 exemple.message("réception d'un message"); // Sera affiché par Display
 return (0);
C#.
Tout comme Itérateur, Observateur est implémenté en C# par l'intermédiaire d'un mot clé : codice_2.
La syntaxe a été simplifiée pour l'abonnement ou appel d'une méthode sur levée d'un événement.
Un événement possède une signature : le type de la méthode que doit lever l'évènement.
Dans cet exemple c'est EventHandler.
event EventHandler observable; 
La signature du type délégué EventHandler est :
void (object emetteur, EventArgs argument)
using System;
///<summary> un observateur </summary>
class Kevin
 public void Reception(object sender, EventArgs e)
 Console.WriteLine("Kevin a reçu : {1} de : {0}", sender.ToString(), e.ToString());
class Program
 ///<summary> la liste d'abonnés </summary>
 static event EventHandler observable;
 static void Main()
 var kevin = new Kevin();
 // enregistrement de Kevin dans la liste d'abonnés
 observable += new EventHandler(kevin.Reception);
 // si la liste n'est pas vide, prévenir les abonnés
 if(observable!=null)
 observable(AppDomain.CurrentDomain, new BeerEventArgs() { Bottles = 0 });
/// <summary> que du fonctionnel </summary>
class BeerEventArgs : EventArgs
 public uint Bottles;
 public override string ToString()
 return string.Format("{0} bottle{1}",
 (Bottles > 0) ? Bottles.ToString() : "no more",
 (Bottles > 1) ? "s" : string.Empty);