教你写响应式框架(四)
来源:互联网 发布: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的设计理念,当然,一些经验性的设计方法也起了很大的作用。
- 教你写响应式框架(四)
- 教你写响应式框架(三)
- 教你写响应式框架(一)
- 教你写响应式框架(二)
- 教你写响应式框架(一)
- 教你写Http框架(一)
- 教你写Http框架(三)
- 一起写RPC框架(六)RPC网络模块的搭建四 请求响应---异步"表白","同步"Yes,I do
- 手把手教你写《雷神》游戏(四)
- 写框架思路进程(四)
- 教你写Android网络框架
- 教你写Android ImageLoader框架
- 基于MFC框架的C++游戏开发(四)键盘响应和鼠标响应
- 教你写Http框架(二)——三个例子带你深入理解AsyncTask
- Android 框架炼成 教你如何写组件间通信框架EventBus(三)
- 【25】手把手教你响应式布局(一)
- <WP7>(四)手把手教你写天气预报程序:本地数据库SQL CE,XML数据解析
- 一步一步教你写股票走势图——分时图四(高亮联动)
- 珍爱生命,远离剩菜!——川大食堂狂想曲
- 利用外观模式模拟股民炒股 C++
- 决策树对比
- I
- Timer
- 教你写响应式框架(四)
- 41.影响iOS6与iOS7屏幕适配的参数和因素
- python基础练习笔记
- nrf51822 ---ancs(2)
- could not bind to address 0.0.0.0:443 no listening sockets available, shutting d
- VMware VirtualBox 不能创建64位虚拟机的原因
- handler 专题
- 博主面试经历
- 位排序学习笔记