教你写响应式框架(四)

来源:互联网 发布:linux查看文件大小m 编辑:程序博客网 时间:2024/06/11 22:17

为什么要这么做?

在教你写响应式框架(三)中,我们还留有一个问题没有说明:为什么OperatorMap中的泛型和Operator中泛型参数的位置正好是相反的?

Operator本身是对Observable发射的数据进行转换的,因此往往出现operator转换之后返回的数据类型发生变化,这时候将泛型参数颠倒一下,就可以保证call方法返回的Observer能够订阅Observable发射出的数据。举个例子来说明:

 Observable<Integer> observable = Observable.create(new Observable.OnAttach<String>() {            @Override            public void call(Observer<? super String> observer) {                observer.update("1");            }        }).map(new IFun<String, Integer>() {            @Override            public Integer call(String s) {                return Integer.valueOf(s);            }        });        observable.attach(new Observer<Integer>() {            @Override            public void update(Integer aFloat) {                System.out.println(aFloat);            }        });

在上面的代码中,map操作符的操作参数为IFun<String,Integer>,而为了使map操作产生的Observer能够订阅create()方法产生的Observable,这时的OperatorMap中的call方法需要产生Observer<String>类型的对象,这使你会发现简单的泛型参数对掉就可以轻松的解决了这个问题。这是来看一下OperatorMap中的call方法:

  public Observer<? super T> call(Observer<? super R> observer) {        return new Observer<T>() {            @Override            public void update(T t) {                observer.update(convert.call(t));            }        };    }

到现在为止,我们已经解决的一些问题,接下来,我们就来看看如何扩展这个小框架。


扩展,增强现有功能

现在我想要为框架增添过滤操作,该怎么做呢?考虑该操作会只过滤掉不满足条件的元素,而不会改变元素类型,因此我们如下设计该类:

public class OperatorFilter<T> implements Observable.Operator<T, T> {    private IFun<? super T, Boolean> fun;    public OperatorFilter(IFun<? super T, Boolean> fun) {        this.fun = fun;    }    @Override    public Observer<? super T> call(Observer<? super T> observer) {        return new Observer<T>() {            @Override            public void update(T t) {                if (fun.call(t).booleanValue()) {                    observer.update(t);                }            }        };    }}

随后,我们在Observable添加函数:

public <R> Observable<R> filter(IFun<? super T, Boolean> fun) {        return lift(new OperatorFilter(fun));    }

准备工作已经完成,让我们测试一下:

public class Client {    public static void main(String[] args) {        Observable.create(new Observable.OnAttach<Integer>() {            @Override            public void call(Observer<? super Integer> observer) {                for (int i = 0; i < 10; i++) {                    observer.update(new Random().nextInt(10));                }            }        }).filter(integer -> integer > 5)                .map(integer -> "num:" + integer)                .attach(integer -> System.out.println(integer));    }}

运行结果为:

num:8
num:6
num:6
num:9

到现在为止,我们构建出了框架的基本主干,并支持了map和filter操作,尽管它看起来有点low,但本教程的目的更倾向于传递一种响应式编程的理念,让每个人都能理解,拉低响应式框架开发的门槛。

好吧,最后给它起了个牛逼的名字叫做”ErJava”,就是easy Reactive Java的意思。


总结

这四个章节一步一步教你如何设计和改进既有的结构,你发现整个框架从最基础的观察者模式出发,在我们不断的提问中得到演进。这与其他框架的开发流程并没有太大的区别,实际上大部分框架的开发工作在之前都会做一个雏形的设计,随着后面的发展才慢慢得到改善,这正如我们所做的一样。

除此之外,你会发现我们尽可能的遵从OOD的设计理念,当然,一些经验性的设计方法也起了很大的作用。

4 0