告别CSDN后才用缩写写了IT类的博客,但还是习惯了。 最不习惯的是,不要直接用手输markdown语法标记。 (好像是因为我没有切换编辑器)
什么是响应编程? 应收帐款管理系统
计算, reactiveprogrammingisanasynchronousprogrammingparadigmconcernedwithdatastreamsandthepropagationofchange.thismeansthatitbecombecomomcomcommmange . g.Arrays ) ordynamic ) e.g.eventemitters ) datastreamswitheaseviatheemployedprogramminglanguaation andtaninfererededdepepon delexists,whichfacilitatestheautomaticpropagationofthechangeinvolver
- -维基百科
以上说明来自维基百科。 在计算机领域,响应编程是一种以数据流和变化的传播为重点的异步编程范式。 这意味着可以使用编程语言轻松表示静态(例如数组)或动态(例如事件发射器)数据流,并且相关的执行模型具有可估计的依赖关系。 此关系的存在有助于自动传播与数据流相关的更改。
抛开大致的概念,先弄清楚一件事吧。 什么是编程范式?
一般来说,编程是为了解决问题,解决问题有各种各样的观点和想法,其中具有普遍性的模型被归结为范式。 常言道,“面向对象”和“面向过程”都是编程范式。
响应编程是从数据流和变化中解决问题的模型。 所以研究响应编程,就要牢记已经掌握的OO (面向对象,笔者都妄断OO的思想根深蒂固),避免忽视OO钻牛角尖。
为什么是异步的?
在展开这个问题之前,我们先看一个故事,知道。 是个小故事
摘录如下。
冷酷的大神喜欢喝茶,不说废话,烧开水。
登场人物:冷酷的大神,两个水壶(普通的水壶,简称水壶; 回响的水壶,简称回响的水壶)。
1冷酷的大神把水壶放在火上,等待水开。 (同步块)
冷酷的大神觉得自己有点傻
2冷酷的大神把水壶放在火上,去客厅看电视,有时去厨房看有没有出水。 (同步非阻塞)
冷酷的大神还是觉得自己有点傻,高端了,买了鸣笛般的水壶。 热水出来后,可以发出大声的~~~~的噪音。
3冷酷的大神把水壶放在火上,等待水开。 (异步块)
冷酷的大神认为这种蠢事没有什么意义
4冷酷的大神把水壶放在火上,去客厅看电视。 在水壶响之前我不再去看它,响了之后去拿水壶。 (异步非阻塞)
冷酷的大神觉得自己变聪明了。
同步异步只是对水壶来说。 普通水壶,同步; 烧水壶。 虽然可以工作,但是打水壶可以在自己完成后,向冷酷的大神表明水开了。 这比不上普通的水壶。 只能同步让呼叫方轮询自己,导致冷酷的大神效率低下。
闭塞非闭塞,只对冷酷的大神来说。 无地自容的冷酷大神,布洛克; 看电视的冷酷大神,不是方块。 情况1和情况3下冷酷无情的大神是个拦路虎,媳妇叫他也不知道。 3中响水壶是异步的,但对立等狠心的大神意义不大。 因此,可以结合无阻塞地使用典型的异步,以发挥异步效用。
上面的情节还有点问题,但基本上可以说明问题。
回答一定是对一个事件、一个信号(等的记述)做出了反应。 水壶的响应是什么? 当水温达到一定程度时,水壶的反应会响起。 水壶响了,声音传向冷酷的大神,冷酷的大神的反应是去关水壶。
再看普通水壶,水温达到一定程度,水壶没有反应。 水的反应是起泡沫,水滚滚。 只是,这个信号很难传达,必须跑着看,所以冷酷的大神只能通过轮训来推进事情,不能去一边等待消息。
对两个水壶来说,烧开水是堵塞的。 水不烧开的话其他的事情做不了。 (比如为了破坏胡桃带过来吗? )
好的,回到我们的问题。 为什么是异步的?
回到对本质问题的回答。 响应编程本质上是对数据流或某些变化的反应,但由于不知道该变化何时发生,所以他是按照异步、回调的方式处理问题的。
怪圈:大部分博客似乎都是这样说着开始解释RxAndroid的。
就像副标题一样,我在网上搜索的大多数博客都在教RxAndroid的使用方法。 各位,请记住以下几点。
RxAndroid (或RxJava )是一个很好的响应编程框架。
你不需要用rx安卓。
RxAndroid并不像那些博客上的那样容易阅读代码。
这里直接进入第三点。 使用弃丝推荐RxJava的例子。 代码类似于以下内容:
Observable.from(folders)
.flatMap((Func1) (folder) -> { Observable.from(file.listFiles()) })
.filter((Func1) (file) -> { file.getName().endsWith(".png") })
.map((Func1) (file) -> { getBitmapFromFile(file) })
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe((Action1) (bitmap) -> { imageCollectorView.addImage(bitmap) });
就这段代码,是否需要从上到下仔细阅读一遍之后才能才会知道他的意图?
甚至,为了精读代码,他可能是这样:
Observable.from(folders)
.flatMap(new Func1>() {
@Override
public Observable call(File file) {
return Observable.from(file.listFiles());
}
})
.filter(new Func1() {
@Override
public Boolean call(File file) {
return file.getName().endsWith(".png");
}
})
.map(new Func1() {
@Override
public Bitmap call(File file) {
return getBitmapFromFile(file);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1() {
@Override
public void call(Bitmap bitmap) {
imageCollectorView.addImage(bitmap);
}
});
ok,请允许我再问一个问题,如此简介的代码,您打算单独用一个类来放吗?
如果对于任何一个处理类似业务逻辑的rx代码段都使用类来放,可能类数量会爆炸,而且这些类的命名看起来会很奇葩。若不这样,您的业务实现类中将充斥诸如此类不精读不敢确定语义、容易被误修改、不容易测试的代码。面对这样的代码的时候只会是如履薄冰战战兢兢。
我是在反对使用RxAndroid吗?
No,我只是反对滥用Rx,我赞成对某些高度抽象的异步行为使用Rx构建具有语义性的框架代码,例如:编写MVVM分层框架。反对对任何业务细节都去做“一切皆流”的无脑工作。毕竟:业务是需要逐渐迭代发展的,对于有测试代码支撑的、同时有较强语义性的类,我们泛读代码就可以“闻弦歌而知雅意”,对于需要重构何处代码,修改何处逻辑心中有数,而不必将“流”再反转回“实际的相互关系”,再打乱,修改,再组织成流,再恶心下一次迭代,而且,最关键的是“你可能要从很多的流中找出这一个流”。