This article mainly introduces the example of using the Observer Pattern in Java Design Pattern to develop a WeChat public account. The WeChat SDK and other parts of Java will not be detailed here. Only focus on the key parts and the embodiment of the advantages of the observer mode during the development process. Friends in need can refer to
Do you still remember how gangsters cooperate in committing crimes in police movies? When a gang is committing a theft, there are always one or two people standing guard at the door. If there is any sign of trouble, the accomplices inside will be immediately notified to make an emergency retreat. Maybe the person who is cheating doesn’t necessarily know every accomplice inside; and there may be new guys inside who don’t know the one who is cheating. But it doesn't matter. It won't affect the communication between them, because they have already agreed on the secret code.
Haha, the relationship between the watcher and the thief mentioned above is a living example of the observer pattern in reality.
The Observer pattern is also known as the Publish/Subscribe pattern. GOF defines the observer pattern as follows: defines a one-to-many dependency relationship between objects . When the status of an object changes, all objects that depend on it get Notified and updated automatically.
Here let’s talk about an important principle of Object-oriented design - the single responsibility principle. Each object of the system should therefore focus on a discrete abstraction within the problem domain. So ideally, an object does only one thing. This brings many benefits in development: it provides reusability and maintainability, and is also a good basis for reconstruction.
So almost all design patterns are based on this basic Design principle. I think the origin of the observer pattern should be in the processing of GUI and business data, because most of the examples explaining the observer pattern now are on this subject. But the application of the observer pattern is by no means limited to this aspect.
Okay, the understanding of the definition always needs to be analyzed by examples. Today's WeChat service account is quite popular. Let's introduce the observer mode to everyone using the WeChat service account as the background.
Look at a picture:
Each user has 3 lines in the above picture, which have been omitted to make the picture clear.
As shown in the picture above, the service account is our subject, and the user is the observer. Now let’s clarify the functions:
1. The service account is the topic, and the business is pushing messages
2. Observers only need to subscribe to the topic, and new messages will be sent
3. When you don’t want this When receiving topic messages, unsubscribe
4. As long as the service account is still there, there will always be people subscribing
Okay, now let’s take a look at the class diagram of the observer pattern:
The next step is code time. We simulate a WeChat 3D lottery service account and some subscribers.
First start writing our theme Interface , and observer interface:
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); }
Next, the implementation class of the 3D service account:
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>
Simulate two users :
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 + "我要告诉舍友们。"); } }
It can be seen that the service account maintains all users who subscribe to messages from it. When there are new messages in the service account, all users are notified. The entire architecture is a loose coupling. The implementation of the theme does not depend on the user. When a new user is added, the code of the theme does not need to be changed; how the user processes the obtained data has nothing to do with the theme;
Finally, take a look at the test code:
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" ); } }
Output results:
observer1 得到 3D 号码 -->20140420的3D号码是:127, 我要记下来。 observer2 得到 3D 号码 -->20140420的3D号码是:127我要告诉舍友们。 observer1 得到 3D 号码 -->20140421的3D号码是:333, 我要记下来。 observer2 得到 3D 号码 -->20140421的3D号码是:333我要告诉舍友们。
There are many places in JDK or Andorid that implement the observer mode, such as XXXView.addXXXListenter, and of course XXXView.setOnXXXListener It is not necessarily the observer mode, because the observer mode is a one-to-many relationship, and setXXXListener is a 1-to-1 relationship and should be called a callback.
恭喜你学会了观察者模式,上面的观察者模式使我们从无到有的写出,当然了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代码基本都是相同的吧,接口是无法实现代码复用的,而且也没有办法使用组合的模式实现这三个方法的复用,所以我觉得这里把这三个方法在类中实现是合理的。
The above is the detailed content of Example code for developing WeChat official accounts using the observer pattern in Java design patterns. For more information, please follow other related articles on the PHP Chinese website!