[JAVA] Modèle d'observateur compris par Nyanko Partie 1

Aperçu

Le modèle Observer est déroutant, n'est-ce pas? Je voudrais donc expliquer ce schéma avec l'exemple de deux chats mendiant du riz. IMG_0751.JPG

Nyanko à comparaître

** Tama de chat domestique ** Tama habite au 3ème étage de l'appartement. Le propriétaire vit seul. Les fenêtres sont souvent fermées et vous ne sortez pas pour jouer. neko_furikaeri.png

** Tigre de chat errant ** Le tigre vit dans un certain quartier commerçant. Je vais dans les maisons des amoureux des chats et attrape les déchets pour me procurer de la nourriture. run_cat.png

Je pense que c'est probablement le modèle d'observateur le plus simple

Cat.java


public class Cat{//Classe de sujet
    private Human human;
    
    public void setHuman(Human human){// setObserver()
        this.human = human;
    }

    public void call(){// notifyObservers()
        System.out.println("Nya (j'ai faim)");
        this.human.called();
    }
}

Human.java


public class Human{//Classe d'observateur
    public void called(){// notify() or update()
        System.out.println("Donner du croquant");
    }
}

Main.java


    public static void main(String[] args) {
        Cat tama = new Cat();
        Human master = new Human();
        tama.setHuman(master);

        tama.call();
    }
Nya (j'ai faim)
Donner du croquant

Commentaire

uml1.png

Il y a deux points principaux du modèle Observer. La première est que la classe Subject a la classe Observer comme variable membre. En d'autres termes, Tama (classe Cat) a besoin de connaître le propriétaire (classe humaine). Ceci est représenté par la fonction setHuman (= setObserver). La seconde consiste à appeler la classe Observer lorsque la classe Subject change. En d'autres termes, si vous avez faim, vous appellerez le propriétaire. Ceci est représenté par les fonctions Cat.call et Human.called.

Cependant, dans le modèle d'observateur le plus simple, Tama ne peut se souvenir que d'un seul propriétaire. Lorsque vous essayez de vous souvenir d'une autre personne, vous oubliez le propriétaire. Le propriétaire aura les yeux larmoyants.

Main.java


    public static void main(String[] args) {
        Cat tama = new Cat();
        Human master = new Human();
        tama.setHuman(master);

        //L'ami du propriétaire est venu jouer
        Human friend = new Human();
        tama.setHuman(friend);

        //Après cela, vous demanderez de la nourriture à votre ami.
        tama.call();
    }

Structure de base du modèle d'observateur

Les tigres peuvent faire des choses que Tama ne pouvait pas. Le tigre se souvient de différentes maisons et semble en faire le tour chaque fois qu'il a faim.

Cat.java


public class Cat {//Classe de sujet
    private final ArrayList<Human> humans = new ArrayList<>();
    
    public void addHuman(Human human){// addObserver()
        this.humans.add(human);
    }

    public void deleteHuman(Human human){// deleteObserver()
        this.humans.remove(human);
    }

    public void call(){// notifyObservers()
        System.out.println("Nya (j'ai faim)");
        for(Human human : this.humans){
            human.called();
        }
    }
}

Human.java


public class Human {//Classe d'observateur
    public void called(){// notify() or update()
        int dice = new Random().nextInt(99);

        if(dice < 50){
            System.out.println("Ceci est pour vous!");
            
        } else {
            System.out.println("Il n'y a rien aujourd'hui ...");
        }
    }
}

Main.java


public static void main(String[] args) {
    Cat tora = new Cat();
    Human suzuki = new Human();
    Human saito = new Human();
    Human kobayashi = new Human();

    tora.addHuman(suzuki);
    tora.addHuman(saito);
    tora.addHuman(kobayashi);

    tora.call();
}
Nya (j'ai faim)
Il n'y a rien aujourd'hui ...
Ceci est pour vous!
Il n'y a rien aujourd'hui ...

Commentaire

uml2.png

Il existe trois différences particulièrement importantes entre les codes Tama et Tora. Tout d'abord, la variable membre de la classe Subject est désormais une ArrayList. Cela permet aux tigres de mendier de la nourriture sous les avant-toits de plusieurs maisons. Deuxièmement, la fonction de la classe Subject est passée de setObserver à addObserver. Le nom a été modifié car il est désormais possible de définir plusieurs éléments au lieu d'un seul élément. Troisièmement, il est désormais possible non seulement d'enregistrer la classe Observer, mais aussi de la supprimer. La fonction deleteObserver montre son rôle. Les non-propriétaires ont 50% de chances de se nourrir, mais pas les 50% restants. C'est difficile à savoir, mais je ne vais peut-être pas dans une maison qui ne nourrit pas beaucoup (non implémentée).

Généralisation

Rendez le code tigre plus polyvalent et polyvalent. Ensuite, ce sera sous la forme du modèle Observer que vous voyez souvent.

Subject.java


public class Subject {
    private final ArrayList<Observer> observers = new ArrayList<>();
    
    public void addObserver(Observer observer){
        this.observers.add(observer);
    }

    public void deleteObserver(Observer observer){
        this.observers.remove(observer);
    }

    public void notifyObservers(){
        for(Observer observer : this.observers){
            observer.update();
        }
    }
}

Cat.java


public class Cat extends Subject {
    @Override
    public void notifyObservers(){
        System.out.println("Nya (j'ai faim)");
        super.notifyObservers();
    }
}

Observer.java


public interface Observer{
    public void update(); // or notify()
}

Human.java


public class Human implements Observer{
    @Override
    public void update(){
        int dice = new Random().nextInt(99);

        if(dice < 50){
            System.out.println("Ceci est pour vous!");
            
        } else {
            System.out.println("Il n'y a rien aujourd'hui ...");
        }
    }
}

Main.java


public static void main(String[] args) {
    Cat tora = new Cat();
    Human suzuki = new Human();
    Human saito = new Human();
    Human kobayashi = new Human();

    tora.addObserver(suzuki);
    tora.addObserver(saito);
    tora.addObserver(kobayashi);

    tora.notifyObservers();
}
Nya (j'ai faim)
Ceci est pour vous!
Ceci est pour vous!
Il n'y a rien aujourd'hui ...

Commentaire

uml3.png

Il existe trois généralisations et modifications du code tigre. Tout d'abord, la classe Human implémente désormais l'interface Observer. La raison de la prise en sandwich de l'interface Observer sera expliquée avec le troisième changement. Deuxièmement, j'ai extrait les fonctions de la classe Cat en tant que classe Subject. Cela rend la classe Cat, qui est volatile, plus simple. Troisièmement, la classe Subject ArrayList inclut désormais l'interface Observer au lieu de la classe Human. En appelant la fonction Observer.update, vous pouvez appeler la fonction de mise à jour de différentes classes ainsi que la classe Human, ce qui la rend plus polyvalente.

Supplément

  1. La fonction de mise à jour, qui apparaît parfois comme une fonction de notification, affiche la même fonctionnalité.
  2. En java, la classe Subject est la classe Observable et l'interface Observer a le même nom. Je l'ai préparé.
  3. La classe Subject est parfois appelée Event Handler et la classe Observer est parfois appelée Event Listener.

en conclusion

Ce commentaire a été écrit pour ceux qui ont commencé à étudier les modèles de conception, mais qui trouvent le modèle Observer difficile. Si vous lisez ce commentaire, puis relisez le diagramme de classe et les autres commentaires, il sera plus facile de comprendre ce que ce modèle essaie de faire. Veuillez également lire Partie 2 si vous le souhaitez. Aussi, j'apprécierais vos commentaires et vos goûts.

Recommended Posts

Modèle d'observateur compris par Nyanko Partie 1
Modèle d'observateur qui peut être vu dans Nyanko Partie 2
Modèle de conception #Observer
Modèle d'observateur en Java
Exemple de source du modèle Observer réalisé par Java, PHP, Python
Faire du son en programmant la partie 2