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.
** 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.
** 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.
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
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();
}
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 ...
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).
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 ...
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.
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.