Le Modèle Observateur pour les Patterns de Comportement

Le modèle observateur est un pattern de conception fréquemment employé, en particulier dans les interfaces graphiques (GUI) et les architectures de publication-abonnement. Son rôle principal est de réduire le couplage entre les entités observées et les observateurs, minimisant ainsi leurs interdépendances.

Définition : Il établit une relation un-à-plusierus entre objets, de sorte que lorsqu'un objet change d'état, tous les objets qui en dépendent sont notifiés et mis à jour automatiquement.

Scénarios d'utilisation :

  • Situations impliquant des comportements corrélés, où les interactions sont dissociables et non structurelles.
  • Environnements avec des déclenchements d'événements à plusieurs niveaux.
  • Échanges de messages inter-systèmes, tels que les files d'attente de messages ou les bus d'événements.

Illustrons ceci avec un exemple concret : les feux de circulation pour traverser une route. Ici, les véhicules et les piétons agissent comme observateurs, tandis que le feu rouge est l'entité observée. Du point de vue des piétons, lorsque le feu rouge s'allume (le feu vert pour les véhicules s'allume aussi), les véhicules avancent et les piétons s'arrêtent.

Implémentation du code

D'abord, définissons la classe abstraite pour les observateurs :


/**
 * Classe abstraite pour les observateurs
 */
public abstract class Observateur {
    protected abstract void onChangement();
}

Ensuite, créons une classe concrète pour un véhicule :


/**
 * Observateur : véhicule
 */
public class Vehicule extends Observateur {
    @Override
    protected void onChangement() {
        System.out.println("Le feu vert est allumé, je peux avancer");
    }
}

Puis, une classe pour les piétons :


/**
 * Observateur : piéton
 */
public class Pieton extends Observateur {
    @Override
    protected void onChangement() {
        System.out.println("Le feu rouge est allumé, je dois attendre");
    }
}

Passons à l'entité observée, qui gère une collection d'boservateurs :


/**
 * Entité observée : feu de signalisation
 */
public class SujetObserve {
    private List<Observateur> observateurs = new ArrayList<>();

    // Ajouter un observateur
    public void ajouterObservateur(Observateur obs) {
        observateurs.add(obs);
    }

    // Supprimer un observateur
    public void supprimerObservateur(Observateur obs) {
        observateurs.remove(obs);
    }

    // Méthode appelée lors d'un changement d'état
    public void etatModifie() {
        for (Observateur obs : observateurs) {
            obs.onChangement();
        }
    }
}

Voici une classe de test pour illustrer le fonctionnement :


/**
 * Test du modèle observateur
 */
public class TestObservateur {
    public static void main(String[] args) {
        // Créer des observateurs
        Observateur vehicule = new Vehicule();
        Observateur pieton = new Pieton();

        // Créer l'entité observée
        SujetObserve feuSignalisation = new SujetObserve();

        // Enregistrer les observateurs
        feuSignalisation.ajouterObservateur(vehicule);
        feuSignalisation.ajouterObservateur(pieton);

        // Déclencher un changement d'état
        feuSignalisation.etatModifie();
    }
}

Cette approche stocke une liste d'observateurs dans l'entité observée, qui les notifie tous lors d'un changement. Cependant, avec un grand nombre d'observateurs, cela peut entraîner des problèmes de performance. Il convient donc de l'adapter en fonction du contexte, en intégrant par exemple des mécanismes d'optimisation comme l'utilisation de pools de threads.

Étiquettes: modèle observateur patterns de conception événements couplage Java

Publié le 8 juillet à 04h35