Modèle d'observateur
Lorsqu'il existe une relation un-à-plusieurs entre des objets, le modèle Observer est utilisé. Par exemple, lorsqu'un objet est modifié, ses objets dépendants sont automatiquement notifiés. Le modèle d’observateur est un modèle comportemental.
Introduction
Intention : Définir une relation de dépendance un-à-plusieurs entre les objets Lorsque l'état d'un objet change, tous les objets qui en dépendent seront avertis. et automatiquement mis à jour.
Résout principalement : Le problème de la notification à d'autres objets des changements d'état d'un objet, et de la prise en compte de la facilité d'utilisation et du faible couplage pour assurer un haut degré de collaboration.
Quand utiliser : Lorsque l'état d'un objet (objet cible) change, tous les objets dépendants (objets observateurs) seront notifiés et des notifications de diffusion seront effectuées.
Comment résoudre : Grâce à la technologie orientée objet, cette dépendance peut être affaiblie.
Code clé : Il existe une ArrayList dans la classe abstraite pour stocker les observateurs.
Exemples d'application : 1. Lors de l'enchère, le commissaire-priseur observe l'enchère la plus élevée et informe ensuite les autres enchérisseurs d'enchérir. 2. Dans Journey to the West, Wukong a demandé au Bodhisattva de rendre le Garçon Rouge. Le Bodhisattva a aspergé d'eau le sol et a attiré une vieille tortue. Cette tortue était l'observateur. Il a observé l'action du Bodhisattva qui aspergeait l'eau.
Avantages : 1. L'observateur et l'observé sont couplés abstraitement. 2. Établir un mécanisme de déclenchement.
Inconvénients : 1. Si un objet observé a de nombreux observateurs directs et indirects, il faudra beaucoup de temps pour avertir tous les observateurs. 2. S'il existe une dépendance cyclique entre l'observateur et la cible d'observation, la cible d'observation déclenchera des appels cycliques entre eux, ce qui peut provoquer un crash du système. 3. Le mode observateur n'a pas de mécanisme correspondant pour permettre à l'observateur de savoir comment l'objet cible observé a changé, mais seulement de savoir que la cible d'observation a changé.
Scénarios d'utilisation : 1. Il existe des méthodes communes à plusieurs sous-classes, et la logique est la même. 2. Les méthodes importantes et complexes peuvent être considérées comme des méthodes modèles.
Remarques : 1. JAVA a déjà des classes de support pour le modèle d'observateur. 2. Évitez les références circulaires. 3. Si elle est exécutée séquentiellement, une erreur d'observateur entraînera le gel du système et une méthode asynchrone est généralement utilisée.
Implémentation
Le modèle observateur utilise trois classes : Sujet, Observateur et Client. L'objet Sujet dispose de méthodes pour lier et dissocier les observateurs de l'objet Client. Nous créons la classe Sujet, la classe abstraite Observateur et la classe d'entité qui étend la classe abstraite Observateur.
ObserverPatternDemo, notre classe de démonstration utilise Subject et des objets de classe d'entité pour démontrer le modèle d'observateur.
Étape 1
Créez la classe Sujet.
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
Créez la classe 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( "Octal String: " + 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( "Hex String: " + Integer.toHexString( subject.getState() ).toUpperCase() ); } }
Étape 4
Utilisez Sujet et les objets observateurs d'entités.
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("First state change: 15"); subject.setState(15); System.out.println("Second state change: 10"); subject.setState(10); } }
Étape 5
Vérifiez la sortie.
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