RxJava2.1.14源码学习(一)基本流程(附带装饰者模式、观察者模式说明)

RxJava已经是日常开发必备的技能,连带面试也是常问的知识点,如果你还停留在是用的层次是远远不够的(因为还不够流弊),基本上现在出去面试,一般都是问一下你都用了什么技术,知不知道它的实现原理(心中犹如万马奔腾,头发都快掉光了,还天天源码源码。。。)?但是没办法,为了生活,为了提升自己的档次(方便吹),也要继续学习,我爱工作!我爱学习!

废话说了不说,先介绍一下大概的内容,本系列主要是涉及RxJava是如何实现函数式编程的,主要知识点:
(1)订阅是如何实现的?观察者模式
(2)多个操作符一起使用,它是如何连接起来的呢?装饰者模式
现在先从观察者模式开始介绍,然后步步深入。

订阅?观察者模式

在所有的设计模式当中,观察者模式算是在日常当中比较经常使用的了(有时候你使用了,可能你不知道)。我们先从它的定义开始:

土话:甲方(观察者)对乙方(被观察者)高度关注,一旦乙方状态发生变化,甲方马上就能收到反馈。之前看过一个现实版本的比喻,警察(观察者)抓小偷(被观察者),自己领悟。。。

现在来一段基础的RxJava使用代码,我们一起看一下:

Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
            }
        }).subscribe(new Observer<Integer>() {
            @Override
            ...
            @Override
            public void onNext(Integer integer) {
                //这里接收到的integer就是1
            }
            ...
        });

有没有发现有点意思?我Observer订阅你Observable,Observable发送了一个1,我Observer就收到了一个1,是不是就是一种观察者模式的应用?

好啦,如果懂什么是观察者模式的,上面这一段可以忽略。

操作符的使用及装饰者模式

一样,先介绍一下装饰者模式的定义:

土话:当觉得一个类的功能不够流弊的时候,我们需要给他扩展能力,有几种方式
(1)子类继承重写
(2)实现新接口
(3)我和目标对象实现相同的目标接口,然后在相应方法里面除了调用目标的,还加上了自己的(装饰者模式的使用)

所以简单来说就是为对象动态扩展功能
举个例子:这两年线上的培训课(特点:学员可以根据自己的时间来安排学习时间–>动态)发展的是如火如荼,假设小明现在是一个基础Android开发工程师,作为祖国未来花朵,他积极向上,勤奋刻苦,在工作之余报了一个Android高级培训班,在培训之前,小明只会写一些基础代码,耦合高,自己都不忍直视。培训之后,他学会了设计模式,会搭建一些简单框架,于是他重构了一下自己的代码,耦合低了,心情也愉快了。这个培训的过程就是一个装饰小明(动态增强其能力)的过程。

现在我们使用RxJava编写一个简单的案例来分析其流程和装饰者模式的使用:

 Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
            }
        })
                //新增
                .map(new Function<Integer, String>() {
                    @Override
                    public String apply(Integer integer) throws Exception {
                        return String.valueOf(integer);
                    }
                })
                .subscribe(new Observer<String>() {
           ...
           @Override
           public void onNext(String result) {
               //收到的值类型发生变化
           }
           ...
        });

在这里我们不禁会感到疑问,最开始是一个Observable对象被Observer观察,现在怎么多了个map,Observer还是可以观察到呢,只不过是数据类型改变了?我们开始深入敌营:

//Observable
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
    //辅助类,检查对象是否为空
    ObjectHelper.requireNonNull(source, "source is null");
    //默认返回ObservableCreate对象(hook功能默认没有开启)
    return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}

从上面可以看出其实就是返回了一个ObservableCreate对象,而我们传入的ObservableOnSubscribe对象被ObservableCreate保存为成员变量。接下来继续看map操作符:

@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
    //空检查
    ObjectHelper.requireNonNull(mapper, "mapper is null");
    //传入Observable和Function对象,返回ObservableMap对象(hook功能默认没有开启)
    return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
}

在ObservableMap的构造里面依然只是保存了这两个成员变量,这里将ObservableCreate包装成了ObservableMap对象,下面就是subscribe了:

@SchedulerSupport(SchedulerSupport.NONE)
    @Override
    public final void subscribe(Observer<? super T> observer) {
        //空检查
        ObjectHelper.requireNonNull(observer, "observer is null");
        ...
            //默认无hook功能,直接返回observer
            observer = RxJavaPlugins.onSubscribe(this, observer);
            //空检查
            ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
            //真正订阅逻辑函数
            subscribeActual(observer);
       ...
    }

//抽象方法,参数为观察者对象
protected abstract void subscribeActual(Observer<? super T> observer);

好了,从上面我们可以发现,我现在已经具备了一个Observer对象,然后调用了subscribeActual函数,subscribeActual函数是抽象的由子类实现,当前的子类是ObservableMap,因为刚刚经由map转化,它把原来的包装了一下,我们看一下它的实现,注意啦注意啦,要开车啦:

@Override
public void subscribeActual(Observer<? super U> t) {
     source.subscribe(new MapObserver<T, U>(t, function));
}

我们发现,ObservableMap的subscribeActual直接调用了sourcesubscribe函数,现在由两个问题,第一是source是什么?答案就是我们在上一步(这里是第一步)传入的ObservableCreate对象,就是说这里调用了ObservableCreatesubscribe函数。第二参数是什么呢,参数是MapObserver,它把我们原来的Observer对象t包装成MapObserver对象,我们现在去看看ObservableCreate的subscribe,发现它并没有实现,而是复用了父类Observable的subscribe,就是我们上面看到的那一段代码,所以直接看ObservableCreatesubscribeActual函数即可:

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函数。这里是MapObserver
    observer.onSubscribe(parent);

    try {
        //回调订阅,此处为ObservableCreate订阅ObservableOnSubscribe
        source.subscribe(parent);
    } catch (Throwable ex) {
        Exceptions.throwIfFatal(ex);
        parent.onError(ex);
    }
}

我们先看一下MapObserver的onSubscribe,它自己并没有实现,而是由父类BasicFuseableObserver实现:

@SuppressWarnings("unchecked")
@Override
public final void onSubscribe(Disposable s) {
    //期待当前Disposable对象为null,新值s不为null,返回true,否则返回false
    if (DisposableHelper.validate(this.s, s)) {
        //为当前Disposable对象赋值
        this.s = s;
        if (s instanceof QueueDisposable) {
            this.qs = (QueueDisposable<T>)s;
        }

        //没有重写默认为true(控制是否继续访问onSubscribe函数)
        if (beforeDownstream()) {
            //actual是下游的Observer对象。
            //此处为我们在subscribe中实现的Observer的匿名对象(即这里回调了我们实现的Observer的onSubscribe函数)
            actual.onSubscribe(this);
            //调用onSubscribe之后的操作,默认为空实现
            afterDownstream();
        }

    }
}

我们继续看下面的代码ObservableOnSubscribe对象调用subscribe函数,就是我们示例代码中重写的subscribe函数,我们回过头去看一下:

 @Override
 public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
        emitter.onNext(1);
}

到这里一整个流程就通了,我们从头开始理一下。
大致流程图
不知道这个流程图看不看得懂(美术小学没毕业,望见谅!!!),大致流程是这样的:
(1)通过Observable.create创建了一个ObservableCreate对象,这个对象保存了我们实现的匿名实现类ObservableOnSubscribe
(2)通过map,创建了一个ObservableMap对象,这个对象保存了(1)中的ObservableCreate对象。
(3)通过subscribe,实现了ObservableMapObserver的订阅(不要奇怪是不是反了,这样是为了连续性)。
(4)在ObservableMap实现了对Observer的订阅时,内部会调用保存的ObservableCreate对象对MapObserver对象进行订阅(构造MapObserver对象,会将Observer保存在MapObserver的成员变量actual中)
(5)在ObservableCreate对象实现了对MapObserver的订阅时,ObservableCreate保存的ObservableOnSubscribe对象会对CreateEmitter对象进行了订阅(构造CreateEmitter对象时,保存了MapObserver)

完成了从上游到下游,再从下游到上游的流程之后,我们开始分析事件,它是什么时候开始发射,又都发射了一些什么事件?我们从最上游的ObservableOnSubscribesubscribe函数开始:

new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
         emitter.onNext(1);
    }
}

什么鬼?这不就是我们示例代码里面写的嘛?要不然你以为呢。。。这里有两个地方要关注,分别是emitter参数和它调用的事件。这个emitter参数看着有点熟悉,当然,因为上面从下游到上游的最后一步我们提到了一个CreateEmitter,它就是ObservableEmitter的自实现类。所以说这个emitter就是在上面我们订阅传递过来的CreateEmitter对象。

这里我们通过EmitterCreate发射了一个onNext事件,我们看一下流程,从EmitterCreate的onNext函数开始:

 @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;
      }
      //是否断开连接,没有断开则继续调用下游传递过来的Observer对象的onNext函数
      if (!isDisposed()) {
         observer.onNext(t);
      }
}

很明显这里的主要逻辑在observer.onNext(t);,这个observer对象在上面我们提高过,就是MapObserver对象,我们继续看:

@Override
public void onNext(T t) {
     if (done) {
          return;
     }

     if (sourceMode != NONE) {
          actual.onNext(null);
          return;
     }

     U v;

     try {
         //确认通过mapper.apply转化的结果不为空
          v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
     } catch (Throwable ex) {
          fail(ex);
          return;
     }
     //回调actual的onNext
     actual.onNext(v);
 }

MapObserver的onNext中有两个地方要关注:
(1)ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
关注这个干什么,不就是校验不为空,返回原值吗?对的,你说得对,不过注意这里调用了一个apply函数,在这里正好就实现了我们示例代码中发射出来的值由Integer到String的装换。

new Function<Integer, String>() {
   @Override
   public String apply(Integer integer) throws Exception {
       //将Integer -> 转换为String
        return String.valueOf(integer);
   }
}

这样的设计真的是太精妙了(请原谅我这个渣渣的偶像情节)。

(2) actual.onNext(v);
这里的actual就是我们刚才所说的Observer对象,即我们自己实现的观察者对象,这样我们发射的Integer类型的1,到这里就变成了String类型的1了。

到这里整个流程从订阅到事件的发射接收就都完成了。可能有人会问说好的装饰者呢?其实在上面的分析已经说明了,主要是两个特点:
(1)层层包装。例如把ObservableCreate包装成ObservableMap,把Observer包装成MapObserver等。
(2)在包装的同时扩展其功能。比如从ObservableCreateObserverMap,ObserverMap即保存了原有引用后面使用,还扩展了转化的功能(构造保存Function对象),在事件发射回调下游的Observer时,调用了Function对象mapperapply函数。

其实之前看别人文章也有说使用适配器模式的,从不同的角度看待问题可能结果会有所偏差,设计模式博大精深,重在思想,个人可能会比较偏向装饰者吧,大牛若是有不同意见,请轻虐o(╥﹏╥)o

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值