观察者模式是什么?百度上面的解释不少吧。如果之前并没有深入了解过,是不是看完之后,和我一样,一脸的问号?????
先看下比较官方的解释:
定义:定义对象间一种一对多的依赖关系,使得当每一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。
本来就不懂的我,表示看完之后都有些怀疑自己的职业生涯了。
俗话说,没有学不会的学生,只有不会教的老师,除非…. 没有除非!
我们看下扔物线给 Android 开发者的 RxJava 详解中对观察者模式的理解吧:
如果你还没看懂,那就让本大(垃)神(圾)来给你讲解下吧:
首先,从android 内部的onclickListener说起。
话说,我们在写点击事件的时候是怎么写?
必然是像这样:
findViewById(R.id.tv_hello).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
然后我们点击去看setOnClickListener的源码,发现参数OnClickListener是一个接口,里面有一个抽象方法 void onClick(View v);,是的,没错,就是上面你写的,这有什么问题?
right!that is the point!
How did it work?!
额….. sorry,戏过了!
言归正传!总觉得有些不对,是不是?
来,让我一句点醒你:setOnclickListener方法是给OnClickListener对象赋值,然后,在View中保存此对象的引用,在需要触发onClick事件的地方,直接使用 此对象的引用去调用onClick方法。
看view中的源码可知:
getListenerInfo().mOnClickListener = l;是保存onClickListener对象的应用
public void setOnClickListener(@Nullable OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
getListenerInfo().mOnClickListener = l;
}
而在下面这两个方法中,直接用此引用调用onclick方法即可。
总结:通过接口interface将需要实现的功能抽取成一个方法,并在需要调用的地方调用(需要执行对监听到的动作做出处理的地方调用),但是这个方法内部实现的内容则是通过实现类(你来实现)去做。这也就可以解释Button是如何 自动调用 onclick方法了。(个人理解,所谓的观察者模式,其实其理论基础还是,接口的作用—抽象父类引用(接口)持有子类对象(实现类)调用方法(实现类的方法)【原谅我一本正经的胡说八道】)
继续看扔物线给 Android 开发者的 RxJava 详解中对观察者模式的理解吧:
Observable的创建create方法,参数是一个接口ObservableOnSubscribe
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
}
})
(RxJavaPlugins.onAssembly()这个方法先不用管,以后再讲)
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
再看ObservableCreate这个类,是 Observable的子类,构造中持有ObservableOnSubscribe的引用,实现了subscribeActual()方法(真正订阅方法),此方法中调用了ObservableOnSubscribe的subscirbe()方法,传入了一个CreateEmitter实例
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
......
由此,引出了被观察者的事件发射器 (Emitter),CreateEmitter是ObservableCreate的一个内部类,它实现了两个接口,这两个接口很重要:一个是ObservableEmitter,一个是Disposable
首先看第一个ObservableEmitter(被观察者发射器):
本身是一个接口interface,继承了Emitter,也是一个interface。Emitter接口中的三个方法值得注意:
public interface Emitter<T> {
void onNext(@NonNull T value);
void onError(@NonNull Throwable error);
void onComplete();
}
用过Rxjava2.0肯定知道,这个和Observer中方法基本一致:
public interface Observer<T> {
void onSubscribe(@NonNull Disposable d);
void onNext(@NonNull T t);
void onError(@NonNull Throwable e);
void onComplete();
}
但是还少一个方法onSubscribe()。
别急,看下onSubscribe的参数就知道了,正是Disposable 接口!
由此,可以猜测,被观察者(Observable)与观察者(Observer)建立联系的关键就在CreateEmitter中! 查看源码,果不其然
首先构造函数中,持有Observer对象,其次,onNext和onComplete中真正调用的都是Observer中的方法。
@Override
public void onNext(T t) {
if (t == null) {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
if (!isDisposed()) {
observer.onNext(t);
}
}
但是在调用之前,会先进行一次判断isDisposed()方法。这也就是为什么在实现Observer时能够通过改变disposed值可以断开事件传递的原因
... ...
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
d.dispose();
}
@Override
public void onNext(@NonNull String s) {
}
@Override
public void onError(@NonNull Throwable e) {
}
@Override
public void onComplete() {
}
});