教你写响应式框架(四)

为什么要这么做?

教你写响应式框架(三)中,我们还留有一个问题没有说明:为什么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的设计理念,当然,一些经验性的设计方法也起了很大的作用。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值