Menu
Coddy logo textTech

Patron Observateur

Fait partie de la section Programmation Orientée Objet du Journey Java de Coddy — leçon 68 sur 87.

Le Patron d'Observation (Observer Pattern) est un patron de conception comportemental qui établit une relation de un à plusieurs entre les objets. Lorsqu'un objet (le sujet) change d'état, tous ses dépendants (les observateurs) sont automatiquement notifiés et mis à jour. Considérez cela comme un abonnement à une newsletter : les abonnés reçoivent des mises à jour chaque fois qu'un nouveau contenu est publié.

Le patron comporte deux composants principaux : un sujet qui maintient une liste d'observateurs et les informe des changements, et des observateurs qui définissent une méthode de mise à jour pour répondre aux notifications :

import java.util.ArrayList;
import java.util.List;

interface Observer {
    void update(String message);
}

class NewsPublisher {
    private List<Observer> subscribers = new ArrayList<>();
    
    public void subscribe(Observer observer) {
        subscribers.add(observer);
    }
    
    public void unsubscribe(Observer observer) {
        subscribers.remove(observer);
    }
    
    public void publish(String news) {
        for (Observer subscriber : subscribers) {
            subscriber.update(news);
        }
    }
}

class EmailSubscriber implements Observer {
    private String email;
    
    public EmailSubscriber(String email) {
        this.email = email;
    }
    
    public void update(String message) {
        System.out.println("Email to " + email + ": " + message);
    }
}

Lorsque l'éditeur publie des actualités, tous les abonnés sont notifiés automatiquement :

NewsPublisher publisher = new NewsPublisher();
publisher.subscribe(new EmailSubscriber("alice@mail.com"));
publisher.subscribe(new EmailSubscriber("bob@mail.com"));

publisher.publish("Breaking news!");
// Sortie :
// Email à alice@mail.com : Breaking news!
// Email à bob@mail.com : Breaking news!

Le patron de conception Observateur favorise un couplage faible — le sujet n'a pas besoin de connaître les classes concrètes de ses observateurs, seulement qu'ils implémentent l'interface Observer. Cela permet d'ajouter facilement de nouveaux types d'observateurs sans modifier le sujet.

challenge icon

Défi

Facile

Construisons un système d'alerte de cours boursiers en utilisant le modèle Observer (Observateur) ! Vous allez créer un système où un téléscripteur boursier (stock ticker) informe plusieurs investisseurs chaque fois que le prix de l'action change, permettant à chaque investisseur de réagir aux mises à jour de prix à sa manière.

Vous organiserez votre code sur quatre fichiers :

  • Observer.java : Définissez l'interface Observer que tous les investisseurs implémenteront. Elle doit déclarer une seule méthode update(String stockName, double price) que les observateurs utilisent pour recevoir des notifications sur les changements de prix.
  • StockTicker.java : Créez la classe sujet qui maintient une liste d'observateurs et les informe des changements de prix. Votre StockTicker doit avoir :

    Un champ String privé pour le nom de l'action (défini via le constructeur).

    Un champ double privé pour le prix actuel (initialement 0).

    Une liste privée pour stocker les observateurs abonnés.

    Une méthode subscribe(Observer observer) qui ajoute un observateur à la liste.

    Une méthode unsubscribe(Observer observer) qui supprime un observateur de la liste.

    Une méthode setPrice(double price) qui met à jour le prix puis informe tous les observateurs en appelant leur méthode update avec le nom de l'action et le nouveau prix.

  • Investors.java : Créez deux types différents d'investisseurs qui implémentent l'interface Observer :

    DayTrader - possède un champ de nom privé défini via le constructeur. Lors de la mise à jour, affiche [name] received alert: [stockName] is now $[price] - Making quick trade!

    LongTermInvestor - possède un champ de nom privé défini via le constructeur. Lors de la mise à jour, affiche [name] received alert: [stockName] is now $[price] - Holding steady.

    Formatez le prix avec deux décimales.

  • Main.java : Rassemblez votre système d'observateurs ! Vous recevrez trois entrées : le nom de l'action (String), la première mise à jour de prix (double) et la deuxième mise à jour de prix (double).

    Créez un StockTicker avec le nom d'action donné. Créez un DayTrader nommé "Alice" et un LongTermInvestor nommé "Bob", et abonnez les deux au téléscripteur.

    Définissez le prix sur la première valeur d'entrée (tous les observateurs sont informés). Ensuite, désabonnez Alice. Enfin, définissez le prix sur la deuxième valeur d'entrée (seul Bob devrait être informé cette fois).

Vous recevrez trois entrées dans l'ordre : le nom de l'action (String), le premier prix (double), le deuxième prix (double).

Ce défi démontre la puissance du modèle Observer : le StockTicker ne sait rien des types d'investisseurs spécifiques — il sait simplement qu'ils implémentent Observer. Lorsque vous désabonnez Alice, elle cesse de recevoir des mises à jour tandis que Bob continue d'être informé. Ce couplage lâche facilite l'ajout de nouveaux types d'investisseurs sans modifier le téléscripteur !

Aide-mémoire

Le Pattern Observateur est un patron de conception comportemental qui établit une relation de un à plusieurs entre des objets. Lorsqu'un objet (le sujet) change d'état, tous ses dépendants (les observateurs) sont automatiquement notifiés et mis à jour.

Le patron implique deux composants principaux :

  • Sujet : Maintient une liste d'observateurs et les informe des changements
  • Observateurs : Définissent une méthode de mise à jour pour répondre aux notifications

Structure de base :

import java.util.ArrayList;
import java.util.List;

interface Observer {
    void update(String message);
}

class Subject {
    private List<Observer> observers = new ArrayList<>();
    
    public void subscribe(Observer observer) {
        observers.add(observer);
    }
    
    public void unsubscribe(Observer observer) {
        observers.remove(observer);
    }
    
    public void notifyObservers(String message) {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }
}

class ConcreteObserver implements Observer {
    public void update(String message) {
        // Réagir à la notification
    }
}

Exemple d'utilisation :

Subject subject = new Subject();
subject.subscribe(new ConcreteObserver());
subject.notifyObservers("State changed!");
// Tous les observateurs abonnés reçoivent la mise à jour

Le Pattern Observateur favorise le couplage faible — le sujet n'a pas besoin de connaître les classes concrètes de ses observateurs, seulement qu'ils implémentent l'interface Observer. Cela facilite l'ajout de nouveaux types d'observateurs sans modifier le sujet.

Essayez vous-même

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Lire les entrées
        String stockName = scanner.nextLine();
        double firstPrice = scanner.nextDouble();
        double secondPrice = scanner.nextDouble();
        
        // TODO: Créer un StockTicker avec le nom d'action donné
        
        // TODO: Créer un DayTrader nommé "Alice"
        
        // TODO: Créer un LongTermInvestor nommé "Bob"
        
        // TODO: Abonner Alice et Bob au ticker
        
        // TODO: Définir le prix à firstPrice (les deux observateurs sont notifiés)
        
        // TODO: Désabonner Alice
        
        // TODO: Définir le prix à secondPrice (seul Bob est notifié)
        
        scanner.close();
    }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet