Cet article présente principalement l'exemple d'utilisation du Observer Pattern en JavaDesign Pattern pour développer un compte public WeChat. Le SDK WeChat et d'autres parties de Java ne seront pas détaillés ici. . Concentrez-vous uniquement sur les éléments clés et l'incarnation des avantages du mode observateur pendant le processus de développement. Les amis dans le besoin peuvent s'y référer
Vous souvenez-vous encore de la façon dont les gangsters ont coopéré pour commettre des crimes dans les films policiers. ? Lorsqu'un gang commet un vol, il y a toujours une ou deux personnes qui montent la garde à la porte. S'il y a le moindre signe de problème, les complices à l'intérieur seront immédiatement avertis pour se retirer d'urgence. Peut-être que la personne qui triche ne connaît pas nécessairement tous ses complices ; et il peut y avoir de nouveaux gars à l’intérieur qui ne connaissent pas celui qui triche. Mais cela n'a pas d'importance, cela n'affectera pas la communication entre eux, car ils se sont déjà mis d'accord sur le code secret.
Haha, la relation entre l'observateur et le voleur mentionnée ci-dessus est un exemple vivant du modèle d'observateur dans la réalité.
Le modèle Observer est également connu sous le nom de modèle Publier/Abonner. GOF définit le modèle d'observateur comme suit : Définissez une relation de dépendance un-à-plusieurs entre les objets Lorsque l' état d'un objet change, tous les objets qui en dépendent sont notifiés et mis à jour. automatiquement.
Ici, je vais d'abord parler d'un principe important de la conception orientée objet : le principe de responsabilité unique. Chaque objet du système doit donc se concentrer sur une abstraction discrète dans le domaine du problème. Idéalement, un objet ne fait qu’une seule chose. Cela apporte de nombreux avantages en matière de développement : cela permet la réutilisabilité et la maintenabilité, et constitue également une bonne base pour la reconstruction.
Donc, presque tous les modèles de conception sont basés sur ce principe de conception de base. Je pense que l'origine du modèle d'observateur devrait être dans le traitement des données GUI et commerciales, car la plupart des exemples expliquant le modèle d'observateur portent désormais sur ce sujet. Mais l’application du modèle d’observateur ne se limite en aucun cas à cet aspect.
D'accord, la compréhension des définitions nécessite toujours des exemples à analyser. Les comptes de service WeChat d'aujourd'hui sont très populaires. Utilisons les comptes de service WeChat comme arrière-plan pour vous présenter le mode observateur.
Regardez une image :
Chaque utilisateur dispose des 3 lignes dans l'image ci-dessus, qui ont été omises pour rendre l'image claire.
Comme le montre l'image ci-dessus, le compte de service est notre sujet et l'utilisateur est l'observateur. Clarifions maintenant les fonctions :
1. Le compte de service est le sujet et l'entreprise envoie des messages
2. Les observateurs n'ont qu'à s'abonner au sujet et de nouveaux messages seront envoyés
3. Quand vous ne voulez pas de ça Lorsque vous recevez des messages de sujet, désabonnez-vous
4. Tant que le compte de service est toujours là, il y aura toujours des personnes qui s'abonneront
Bon, regardons maintenant le diagramme de classes de l'observateur modèle :
La prochaine étape est le temps de code. Nous simulons un compte de service de loterie WeChat 3D et certains abonnés.
Commencez d'abord à écrire notre thème interface et notre interface observateur :
package com.zhy.pattern.observer; /** * 主题接口,所有的主题必须实现此接口 * * @author zhy * */ public interface Subject { /** * 注册一个观察着 * * @param observer */ public void registerObserver(Observer observer); /** * 移除一个观察者 * * @param observer */ public void removeObserver(Observer observer); /** * 通知所有的观察着 */ public void notifyObservers(); } package com.zhy.pattern.observer; /** * @author zhy 所有的观察者需要实现此接口 */ public interface Observer { public void update(String msg); }
Ensuite, la classe d'implémentation du compte de service 3D :
package com.zhy.pattern.observer; import java.util.ArrayList; import java.util.List; public class ObjectFor3D implements Subject { private List<observer> observers = new ArrayList<observer>(); /** * 3D彩票的号码 */ private String msg; @Override public void registerObserver(Observer observer) { observers.add(observer); } @Override public void removeObserver(Observer observer) { int index = observers.indexOf(observer); if (index >= 0) { observers.remove(index); } } @Override public void notifyObservers() { for (Observer observer : observers) { observer.update(msg); } } /** * 主题更新消息 * * @param msg */ public void setMsg(String msg) { this.msg = msg; notifyObservers(); } }</observer></observer>
Simulation deux utilisateurs :
package com.zhy.pattern.observer; public class Observer1 implements Observer { private Subject subject; public Observer1(Subject subject) { this.subject = subject; subject.registerObserver(this); } @Override public void update(String msg) { System.out.println("observer1 得到 3D 号码 -->" + msg + ", 我要记下来。"); } }
package com.zhy.pattern.observer; public class Observer2 implements Observer { private Subject subject ; public Observer2(Subject subject) { this.subject = subject ; subject.registerObserver(this); } @Override public void update(String msg) { System.out.println("observer2 得到 3D 号码 -->" + msg + "我要告诉舍友们。"); } }
On peut voir que le compte de service conserve tous les utilisateurs qui s'y abonnent. Lorsqu'il y a de nouveaux messages dans le compte de service, tous les utilisateurs sont avertis. L'ensemble de l' architecture est faiblement couplée. L'implémentation du thème ne dépend pas de l'utilisateur. Lorsqu'un nouvel utilisateur est ajouté, le code du thème n'a pas besoin d'être modifié. les données n'ont rien à voir avec le thème ;
Jetez enfin un œil au code du test :
package com.zhy.pattern.observer.test; import com.zhy.pattern.observer.ObjectFor3D; import com.zhy.pattern.observer.Observer; import com.zhy.pattern.observer.Observer1; import com.zhy.pattern.observer.Observer2; import com.zhy.pattern.observer.Subject; public class Test { public static void main(String[] args) { //模拟一个3D的服务号 ObjectFor3D subjectFor3d = new ObjectFor3D(); //客户1 Observer observer1 = new Observer1(subjectFor3d); Observer observer2 = new Observer2(subjectFor3d); subjectFor3d.setMsg("20140420的3D号码是:127" ); subjectFor3d.setMsg("20140421的3D号码是:333" ); } }
Résultat de sortie :
observer1 得到 3D 号码 -->20140420的3D号码是:127, 我要记下来。 observer2 得到 3D 号码 -->20140420的3D号码是:127我要告诉舍友们。 observer1 得到 3D 号码 -->20140421的3D号码是:333, 我要记下来。 observer2 得到 3D 号码 -->20140421的3D号码是:333我要告诉舍友们。
Il existe de nombreux endroits dans JDK ou Andorid qui implémentent le mode observateur, comme XXXView.addXXXListener, bien sûr XXXView.setOnXXXListener n'est pas nécessairement le mode observateur, car le mode observateur est une relation un-à-plusieurs, et setXXXListener est une relation 1-à-1 et doit être appelé un rappel.
恭喜你学会了观察者模式,上面的观察者模式使我们从无到有的写出,当然了java中已经帮我们实现了观察者模式,借助于java.util.Observable和java.util.Observer。
下面我们使用Java内置的类实现观察者模式:
首先是一个3D彩票服务号主题:
package com.zhy.pattern.observer.java; import java.util.Observable; public class SubjectFor3d extends Observable { private String msg ; public String getMsg() { return msg; } /** * 主题更新消息 * * @param msg */ public void setMsg(String msg) { this.msg = msg ; setChanged(); notifyObservers(); } }
下面是一个双色球的服务号主题:
package com.zhy.pattern.observer.java; import java.util.Observable; public class SubjectForSSQ extends Observable { private String msg ; public String getMsg() { return msg; } /** * 主题更新消息 * * @param msg */ public void setMsg(String msg) { this.msg = msg ; setChanged(); notifyObservers(); } }
最后是我们的使用者:
package com.zhy.pattern.observer.java; import java.util.Observable; import java.util.Observer; public class Observer1 implements Observer { public void registerSubject(Observable observable) { observable.addObserver(this); } @Override public void update(Observable o, Object arg) { if (o instanceof SubjectFor3d) { SubjectFor3d subjectFor3d = (SubjectFor3d) o; System.out.println("subjectFor3d's msg -- >" + subjectFor3d.getMsg()); } if (o instanceof SubjectForSSQ) { SubjectForSSQ subjectForSSQ = (SubjectForSSQ) o; System.out.println("subjectForSSQ's msg -- >" + subjectForSSQ.getMsg()); } } }
看一个测试代码:
package com.zhy.pattern.observer.java; public class Test { public static void main(String[] args) { SubjectFor3d subjectFor3d = new SubjectFor3d() ; SubjectForSSQ subjectForSSQ = new SubjectForSSQ() ; Observer1 observer1 = new Observer1(); observer1.registerSubject(subjectFor3d); observer1.registerSubject(subjectForSSQ); subjectFor3d.setMsg("hello 3d'nums : 110 "); subjectForSSQ.setMsg("ssq'nums : 12,13,31,5,4,3 15"); } }
测试结果:
subjectFor3d's msg -- >hello 3d'nums : 110 subjectForSSQ's msg -- >ssq'nums : 12,13,31,5,4,3 15
可以看出,使用Java内置的类实现观察者模式,代码非常简洁,对了addObserver,removeObserver,notifyObservers都已经为我们实现了,所有可以看出Observable(主题)是一个类,而不是一个接口,基本上书上都对于Java的如此设计抱有反面的态度,觉得Java内置的观察者模式,违法了面向接口编程这个原则,但是如果转念想一想,的确你拿一个主题在这写观察者模式(我们自己的实现),接口的思想很好,但是如果现在继续添加很多个主题,每个主题的ddObserver,removeObserver,notifyObservers代码基本都是相同的吧,接口是无法实现代码复用的,而且也没有办法使用组合的模式实现这三个方法的复用,所以我觉得这里把这三个方法在类中实现是合理的。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!