AHRIMAN.FR

SCIENCE - NEO-EVHEMERISME - DONJONSDRAGONS

Design pattern : Observer

Ecris par :
Mis en ligne le :
Lu :
97 fois
Twitter Facebook Google Plus Linkedin email

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 »).

Utilité

La notion d'observateur/observable permet de 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.

Illustration

Prenons comme exemple une classe qui produit des signaux (données observables), visualisée à 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 thread 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 contient une liste d'observateurs, ainsi à l'aide d'une méthode de notification l'ensemble des observateurs est prévenu. 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.

EXEMPLE EN C++


#include <string>
#include <set>
#include <iostream>
using namespace std;

class IObserver
{
public:
virtual void update(string data) = 0;
};

class Observable
{
private:
set<IObserver*> list_observers;

public:
void notify(string data) const
{
// Notifier tous les observers
for (set<IObserver*>::const_iterator it = list_observers.begin();
it != list_observers.end(); ++it)
(*it)->update(data);
}

void addObserver(IObserver* observer)
{
// Ajouter un observer a la liste
list_observers.insert(observer);
}

void removeObserver(IObserver* observer)
{
// Enlever un observer a la liste
list_observers.erase(observer);
}
};

class Display : public IObserver
{
void update(string data)
{
cout << "Evenement : " << data << endl;
}
};

class Exemple : public Observable
{
public:
void message(string message)
{
// Lancer un evenement lors de la reception d'un message
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("reception d'un message"); // Sera affiché par Display

return 0;
}

Images

Bibliographie