Patron Observateur

Le patron Observateur est un patron de conception comportemental qui définit une relation de dépendance un-à-plusieurs. Lorsque l'état d'un objet change, tous ses dépendants sont notifiés et se mettent à jour automatiquement.

Lorsqu'il existe une relation un-à-plusieurs entre des objets, utilisez le patron Observateur. Par exemple, lorsqu'un objet est modifié, il notifie automatiquement les objets qui en dépendent. Le patron Observateur est un patron comportemental.

Introduction

intention

Il crée une relation de dépendance un-à-plusieurs entre des objets. Lorsque l'état d'un objet change, tous les objets qui en dépendent sont notifiés et se mettent à jour automatiquement.

Problème principal traité

  • Le patron Observateur résout le problème consistant à notifier automatiquement les autres objets dépendants lorsqu'un objet change d'état, tout en maintenant un faible couplage et une forte collaboration entre les objets.

Cas d'utilisation

  • Lorsqu'un changement d'état d'un objet doit mettre à jour d'autres objets en même temps.

Approche d'implémentation

  • Définir l'interface observateur: contient une méthode de mise à jour.
  • Créer des observateurs concretsImplémente l'interface observateur et définit le comportement lors de la réception d'une notification.
  • Définir l'interface sujetContient des méthodes pour ajouter, supprimer et notifier des observateurs.
  • Créer le sujet concret: implémenter l'interface sujet, gérer la liste des observateurs et notifier les observateurs lorsque l'état change.

Code clé

  • Liste d'observateurs: maintenir une liste d'observateurs dans le sujet.

Exemple d'application

  • Système d'enchères: Le commissaire-priseur joue le rôle du sujet, les enchérisseurs jouent le rôle d'observateurs, et tous les enchérisseurs sont notifiés lorsque le prix de l'enchère est mis à jour.
  • Histoire du Voyage en OccidentLe Bodhisattva aspergeant de l'eau représente le changement d'état, et la vieille tortue joue le rôle de l'observateur, observant ce changement.

Avantages

  • Couplage abstrait: Il existe un couplage abstrait entre les observateurs et le sujet.
  • Mécanisme de déclenchementÉtablit un mécanisme de déclenchement et de notification pour les changements d'état.

Inconvénients

  • Problèmes de performanceS'il y a de nombreux observateurs, le processus de notification peut prendre du temps.
  • Dépendance circulaireCela peut entraîner des appels circulaires et des plantages du système.
  • Manque de détails sur les changements: Les observateurs ne savent pas comment le sujet change, seulement qu'un changement a eu lieu.

Suggestions d'utilisation

  • Utilisez-le lorsque vous devez réduire le couplage entre les objets et lorsque les changements d'état d'un objet doivent déclencher des changements dans d'autres objets.
  • Envisagez d'utiliser les classes de prise en charge du patron Observateur intégrées à Java, telles quejava.util.Observableetjava.util.Observer。

Notes

  • Éviter les références circulaires: Faites attention à la dépendance entre les observateurs et le sujet afin d'éviter les références circulaires.
  • Exécution asynchroneEnvisagez d'utiliser une notification asynchrone pour éviter qu'un point de défaillance unique ne bloque l'ensemble du système.

Structure

Le patron Observateur comprend les rôles principaux suivants :

  • Sujet : également appelé l'observé ou l'observable, il s'agit d'un objet doté d'un état et qui maintient une liste d'observateurs. Le sujet fournit des méthodes pour ajouter, supprimer et notifier des observateurs.
  • Observateur : un observateur est un objet qui reçoit des notifications du sujet. Il doit implémenter une méthode update, qui est appelée pour effectuer des opérations de mise à jour lorsqu'une notification est reçue du sujet.
  • Sujet concret : un sujet concret est une classe d'implémentation concrète du sujet. Il maintient la liste des observateurs et notifie les observateurs lorsque l'état change.
  • Observateur concret : un observateur concret est une classe d'implémentation concrète de l'observateur. Il implémente la méthode update et définit les opérations spécifiques à effectuer lors de la réception d'une notification du sujet.

Le patron Observateur découple le sujet et les observateurs afin d'obtenir un couplage lâche entre les objets. Lorsque l'état du sujet change, tous les observateurs qui en dépendent reçoivent des notifications et se mettent à jour en conséquence.

Implémentation

Le patron Observateur utilise trois classes : Subject, Observer et Client. L'objet Subject possède des méthodes pour lier des observateurs à l'objet Client et dissocier des observateurs de l'objet Client. Nous créons la classeSubject, la classe abstraiteObserveret les classes qui étendent la classe abstraiteObserverclasse d'entité.

ObserverPatternDemo, notre classe de démonstration utiliseSubjectet des objets de la classe d'entité pour démontrer le patron Observateur.

观察者模式的 UML 图

Étape 1

Créer la classe Subject.

Subject.java

import java.util.ArrayList; import java.util.List; public class Subject { private List<Observer> observers = new ArrayList<Observer>(); private int state; public int getState() { return state; } public void setState(int state) { this.state = state; notifyAllObservers(); } public void attach(Observer observer){ observers.add(observer); } public void notifyAllObservers(){ for (Observer observer : observers) { observer.update(); } } }

Étape 2

Créez la classe Observer.

Observer.java

public abstract class Observer { protected Subject subject; public abstract void update(); }

Étape 3

pour créer des classes d'observateur d'entité.

BinaryObserver.java

public class BinaryObserver extends Observer{ public BinaryObserver(Subject subject){ this.subject = subject; this.subject.attach(this); } @Override public void update() { System.out.println( "Binary String: " + Integer.toBinaryString( subject.getState() ) ); } }

OctalObserver.java

public class OctalObserver extends Observer{ public OctalObserver(Subject subject){ this.subject = subject; this.subject.attach(this); } @Override public void update() { System.out.println( "Chaîne octale : " + Integer.toOctalString( subject.getState() ) ); } }

HexaObserver.java

public class HexaObserver extends Observer{ public HexaObserver(Subject subject){ this.subject = subject; this.subject.attach(this); } @Override public void update() { System.out.println( "Chaîne hexadécimale : " + Integer.toHexString( subject.getState() ).toUpperCase() ); } }

Étape 4

UtilisationSubjectet objets observateurs d'entité.

ObserverPatternDemo.java

public class ObserverPatternDemo { public static void main(String[] args) { Subject subject = new Subject(); new HexaObserver(subject); new OctalObserver(subject); new BinaryObserver(subject); System.out.println("Premier changement d'état : 15"); subject.setState(15); System.out.println("Deuxième changement d'état : 10"); subject.setState(10); } }

Étape 5

Exécutez le programme et affichez les résultats :

First state change: 15
Hex String: F
Octal String: 17
Binary String: 1111
Second state change: 10
Hex String: A
Octal String: 12
Binary String: 1010
autres extensions