210 votes

Quand doit-on utiliser Observer et Observable ?

Un interviewer m'a demandé :

Qu'est-ce que Observer y Observable et quand devons-nous les utiliser ?

Je n'étais pas au courant de ces termes, alors quand je suis rentré chez moi et que j'ai commencé à faire des recherches sur Google à propos de Observer y Observable J'ai trouvé quelques points dans différentes ressources :

1) Observable est une classe et Observer est une interface.

2) Le Observable maintient une liste de Observer s.

3) Lorsqu'un Observable est mis à jour, il invoque la méthode update() de chacune de ses Observer pour le notifier, il est modifié.

J'ai trouvé cet exemple :

import java.util.Observable;
import java.util.Observer;

class MessageBoard extends Observable
{
    public void changeMessage(String message) 
    {
        setChanged();
        notifyObservers(message);
    }
}

class Student implements Observer 
{
    @Override
    public void update(Observable o, Object arg) 
    {
        System.out.println("Message board changed: " + arg);
    }
}

public class MessageBoardTest 
{
    public static void main(String[] args) 
    {
        MessageBoard board = new MessageBoard();
        Student bob = new Student();
        Student joe = new Student();
        board.addObserver(bob);
        board.addObserver(joe);
        board.changeMessage("More Homework!");
    }
}

Mais je ne comprends pas pourquoi nous avons besoin Observer y Observable ? Quels sont les setChanged() y notifyObservers(message) méthodes pour ?

0 votes

Le lien ne fonctionne pas. @Androider Pouvez-vous fournir un lien actualisé ?

0 votes

Si vous utilisez Java 6 ou plus, essayez ceci dzone.com/articles/java-ee6-events-lightweight

1 votes

Je vous conseille vivement de lire ce livre pour avoir une bonne compréhension des modèles de conception. Cela peut sembler idiot, mais c'est un excellent outil d'apprentissage.

275voto

duffymo Points 188155

Vous avez un exemple concret d'un étudiant et d'un tableau de messages. L'étudiant s'inscrit en s'ajoutant à la liste des observateurs qui veulent être notifiés lorsqu'un nouveau message est affiché sur le tableau de messages. Lorsqu'un message est ajouté au tableau d'affichage, il parcourt sa liste d'observateurs et les informe que l'événement s'est produit.

Pensez à Twitter. Lorsque vous dites que vous voulez suivre quelqu'un, Twitter vous ajoute à sa liste de suiveurs. Lorsqu'elle envoie un nouveau tweet, vous le voyez dans votre entrée. Dans ce cas, votre compte Twitter est l'Observateur et la personne que vous suivez est l'Observable.

L'analogie n'est peut-être pas parfaite, car Twitter est plus susceptible d'être un médiateur. Mais elle illustre bien le propos.

62voto

jbx Points 4063

En termes très simples (car les autres réponses vous renvoient de toute façon à tous les modèles de conception officiels, alors consultez-les pour plus de détails) :

Si vous voulez avoir une classe qui est surveillée par d'autres classes dans l'écosystème de votre programme, vous dites que vous voulez que la classe soit observable. C'est-à-dire qu'il pourrait y avoir des changements dans son état que vous voudriez diffuser au reste du programme.

Pour ce faire, nous devons appeler une sorte de méthode. Nous ne voulons pas que la classe Observable soit étroitement liée aux classes qui souhaitent l'observer. Elle ne se soucie pas de savoir qui elle est, tant qu'elle remplit certains critères. (Imaginez qu'il s'agisse d'une station de radio, elle ne se soucie pas de savoir qui l'écoute tant qu'une radio FM est réglée sur sa fréquence). Pour cela, nous utilisons une interface, appelée l'observateur.

Par conséquent, la classe Observable aura une liste d'Observateurs (c'est-à-dire des instances implémentant les méthodes de l'interface Observer que vous pourriez avoir). Lorsqu'elle veut diffuser quelque chose, elle appelle simplement la méthode sur tous les observateurs, l'un après l'autre.

La dernière chose pour clore le puzzle est la suivante : comment la classe Observable saura-t-elle qui est intéressé ? La classe Observable doit donc proposer un mécanisme permettant aux Observateurs de faire part de leur intérêt. Une méthode telle que addObserver(Observer o) ajoute en interne l'observateur à la liste des observateurs, de sorte que lorsque quelque chose d'important se produit, il boucle la liste et appelle la méthode de notification respective de l'interface Observer de chaque instance de la liste.

Il se peut qu'au cours de l'entretien, on ne vous ait pas posé de question explicite sur la java.util.Observer y java.util.Observable mais sur le concept générique. Le concept est un modèle de conception, pour lequel Java fournit une prise en charge directe afin de vous aider à le mettre en œuvre rapidement lorsque vous en avez besoin. Je vous suggère donc de comprendre le concept plutôt que les méthodes/classes réelles (que vous pouvez consulter lorsque vous en avez besoin).

UPDATE

En réponse à votre commentaire, l'actuel java.util.Observable La classe offre les installations suivantes :

  1. Tenir à jour une liste de java.util.Observer instances. Les nouvelles instances souhaitant être notifiées peuvent être ajoutées par le biais de la fonction addObserver(Observer o) et retiré par deleteObserver(Observer o) .

  2. Maintien d'un état interne, précisant si l'objet a changé depuis la dernière notification aux observateurs. Ceci est utile car cela sépare la partie où l'on dit que l'objet a changé depuis la dernière notification aux observateurs. Observable a changé, à partir de la partie où vous notifiez les changements. (Par exemple, c'est utile si vous avez plusieurs changements qui se produisent et que vous voulez seulement notifier à la fin du processus plutôt qu'à chaque petite étape). Cela se fait par setChanged() . Donc vous l'appelez juste quand vous avez changé quelque chose au Observable et vous voulez le reste de la Observers pour finir par le savoir.

  3. Notifier à tous les observateurs que le Observable a changé d'état. Cela se fait par le biais de notifyObservers() . Cela permet de vérifier si l'objet a effectivement été modifié (c'est-à-dire qu'un appel à la fonction setChanged() a été faite) avant de procéder à la notification. Il existe 2 versions, l'une sans argument et l'autre avec un argument de type Object au cas où vous voudriez transmettre des informations supplémentaires avec la notification. En interne, ce qui se passe, c'est qu'il faut simplement itérer à travers la liste de Observer et appelle la update(Observable o, Object arg) pour chacun d'entre eux. Cela indique à la Observer qui est l'objet Observable qui a changé (vous pouvez en observer plus d'un), et l'élément supplémentaire Object arg pour transporter potentiellement des informations supplémentaires (transmises par notifyObservers() .

44voto

Mubarak Points 55

Définition

Le modèle de l'observateur est utilisé lorsqu'il existe une relation de type "un à plusieurs" entre les objets. Par exemple, si un objet est modifié, ses objets dépendants sont automatiquement notifiés et les changements correspondants sont effectués sur tous les objets dépendants.

Exemples

  1. Si vous changez d'adresse permanente, vous devez en informer les autorités compétentes en matière de passeport et de carte d'identité. Donc ici l'autorité des passeports et l'autorité des cartes de crédit sont des observateurs et vous êtes un sujet.

  2. Sur Facebook également, si vous vous abonnez à quelqu'un, vous serez averti de toute nouvelle mise à jour.

Quand l'utiliser :

  1. Lorsqu'un objet change d'état, tous les autres objets dépendants doivent automatiquement changer d'état pour maintenir la cohérence.

  2. Lorsque le sujet ne connaît pas le nombre d'observateurs qu'il a.

  3. Quand un objet doit pouvoir notifier d'autres objets sans savoir qui sont ces objets.

Étape 1

Créer une classe de sujets.

Sujet.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éer la classe Observer.

Observer.java

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

Étape 3

Créer des classes d'observateurs concrètes

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 le sujet et les objets concrets de l'observateur.

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.

Premier changement d'état : 15

Chaîne hexagonale : F

Chaîne octale : 17

Chaîne binaire : 1111

Deuxième changement d'état : 10

Chaîne hexagonale : A

Chaîne octale : 12

Chaîne binaire : 1010

1 votes

Bien expliqué :)

3 votes

Je pense que "Définition" est une faute de frappe. J'espère que c'est une faute de frappe.

0 votes

La parole ne vaut rien. Les exemples concrets sont superbes.

11voto

Andy Points 1094

Ils font partie de la Modèle de conception observateur . Généralement, un ou plusieurs obervateurs être informé des changements dans un observable . C'est une notification que "quelque chose" s'est produit, où vous, en tant que programmeur, pouvez définir ce que "quelque chose" signifie.

En utilisant ce modèle, vous découplez les deux entités l'une de l'autre - les observateurs deviennent pluggables.

0 votes

J'apprécierai, si vous ajoutez l'explication de board.changeMessage("More Homework!"); dans votre réponse, je veux dire ce qui se passe quand changeMessage("More Homework!"); invoqué.

10voto

Pawel Solarski Points 465

L'observateur, ou callback, est enregistré dans Observable.

Il est utilisé pour informer, par exemple, sur des événements qui se sont produits à un moment donné. Il est largement utilisé dans Swing, Ajax, GWT pour distribuer des opérations sur les événements de l'interface utilisateur (clics de bouton, champs de texte modifiés, etc.).

Dans Swing vous trouvez des méthodes comme addXXXListener(Listener l), dans GWT vous avez des callbacks (Async).

Comme la liste des observateurs est dynamique, les observateurs peuvent s'enregistrer et se désenregistrer pendant l'exécution. C'est également un bon moyen de découpler les observables des observateurs, puisque des interfaces sont utilisées.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X