观察者模式(异步)
写在前面
- 因为最近比较流行的RxJava\MVC\MVP\MVVM都跟一个叫做观察者模式的东东比较接近,当然这是作为Java开发者最熟悉不过的设计模式,因为在Java中已经默认为开发者实现了这种观察者模式。但是不自己理解的写一写还是收获甚微的
-
在上一篇ReactiveX资料汇总中,我已经分享过一边外文的设计模式,在这在补充一下吧:https://en.wikipedia.org/wiki/Observer_pattern
-
让我们来看看Java中是如何观察者模式的吧,来个实例先:
代码分析
import java.util.Observable;
import java.util.Scanner;
class EventSource extends Observable implements Runnable {
public void run() {
while (true) {
String response = new Scanner(System.in).next();
setChanged();
notifyObservers(response);
}
}
}
import java.util.Observable;
import java.util.Observer;
public class MyApp {
public static void main(String[] args) {
System.out.println("Enter Text: ");
EventSource eventSource = new EventSource();
eventSource.addObserver(new Observer() {
public void update(Observable obj, Object arg) {
System.out.println("Received response: " + arg);
}
});
new Thread(eventSource).start();
}
}
- 首先Java对外提供了简介的被观察者Observable类,想要设置被观察者的行为只要通过继承Observable类并在类的内部实现被观察者自己的行为即可,如果被观察者的操作是耗时操作,我们不能阻塞主线程所以在上面的例子中实现了Runable并在run中实现了自己的操作。
- 当被观察者实现了自己操作的同时,这时候观察者并不知道,因为它采用的不是轮询机制(程序的噩梦),所以被观察者自身发生变化的时候它同时需要负责通知它的观察者,甚至可以具体到某个观察者这就是notifyObservers(params)中参数的作用
- 观察者要做的事情很简单,就是就收到被观察者发来的通知作出相应的操作即可,所以在上面的例子中观察者只做了一件事那就是update,但是我们看到了被观察者是通过addObserver为自己关联上了观察者,那下面让我们看一下Observable源码,你就清楚被观察者的业务了,代码名称起得很规范无需多做解释:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package java.util;
import java.util.Observer;
public class Observable {
public Observable() {
throw new RuntimeException("Stub!");
}
public synchronized void addObserver(Observer o) {
throw new RuntimeException("Stub!");
}
public synchronized void deleteObserver(Observer o) {
throw new RuntimeException("Stub!");
}
public void notifyObservers() {
throw new RuntimeException("Stub!");
}
public void notifyObservers(Object arg) {
throw new RuntimeException("Stub!");
}
public synchronized void deleteObservers() {
throw new RuntimeException("Stub!");
}
protected synchronized void setChanged() {
throw new RuntimeException("Stub!");
}
protected synchronized void clearChanged() {
throw new RuntimeException("Stub!");
}
public synchronized boolean hasChanged() {
throw new RuntimeException("Stub!");
}
public synchronized int countObservers() {
throw new RuntimeException("Stub!");
}
}
- 顺便把观察者的接口源码页贴上吧,这样就是完整的Observer Pattern了
package java.util;
import java.util.Observable;
public interface Observer {
void update(Observable var1, Object var2);
}
总结
- 观察者模式Observer Pattern又叫发布订阅模式Publish/Subscrible,同时里面含有被观察者Subject和观察者Observer两种角色,所以看RxJava和Rxtrofit里面各种眼花缭乱的命名规则,总有种想骂娘的冲动好吧我又浅薄了。。。
- 被观察者除了要完成自己的基本业务的同时还要负责同时某个或者全部的关心它状态的观察者,传达它的当前状态
- 设计模式只是比较好的编程讨论,他千变万化不要拘泥于它表面的形式