[转帖]浅谈响应式编程(Reactive Programming)
浅谈响应式编程(Reactive Programming)
https://www.jianshu.com/p/1765f658200a 例子写的非常好呢.
这是告别CSDN后第一次使用简书写IT类的博客,还在适应。最不适应的就是不能直接手输markdown语法标记。(好像原因是我没有切换编辑器)
什么是响应式编程(Reactive Programming)
In computing, reactive programming is an asynchronous programming paradigm concerned with data streams and the propagation of change. This means that it becomes possible to express static (e.g. arrays) or dynamic (e.g. event emitters) data streams with ease via the employed programming language(s), and that an inferred dependency within the associated execution model exists, which facilitates the automatic propagation of the change involved with data flow.
-- Wikipedia
以上解释来自维基百科,在计算机领域,响应式编程是一个专注于数据流和变化传递的异步编程范式。这意味着可以使用编程语言很容易地表示静态(例如数组)或动态(例如事件发射器)数据流,并且在关联的执行模型中,存在着可推断的依赖关系,这个关系的存在有利于自动传播与数据流有关的更改。
抛开大段大段的概念,我们先搞清楚一件事情:什么是编程范式?
通俗的说:编程是为了解决问题,而解决问题可以有多种视角和思路,其中具有普适性的模式被归结为范式。我们常说的:“面向对象”,“面向过程”都是编程范式。
响应式编程是一种从数据流和变化出发的解决问题的模式。所以要研究响应式编程,一定要牢记已经掌握的OO(面向对象,笔者妄断大家OO的思想都是很根深蒂固了)来做对比,也一定要抛开OO避免钻牛角尖。
为什么是异步?
在展开这个问题前,我们先看一个故事,引自知乎:小故事
摘抄如下:
老张爱喝茶,废话不说,煮开水。
出场人物:老张,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。
1 老张把水壶放到火上,立等水开。(同步阻塞)
老张觉得自己有点傻2 老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞)
老张还是觉得自己有点傻,于是变高端了,买了把会响笛的那种水壶。水开之后,能大声发出嘀~~~~的噪音。3 老张把响水壶放到火上,立等水开。(异步阻塞)
老张觉得这样傻等意义不大4 老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。(异步非阻塞)
老张觉得自己聪明了。所谓同步异步,只是对于水壶而言。普通水壶,同步;响水壶,异步。虽然都能干活,但响水壶可以在自己完工之后,提示老张水开了。这是普通水壶所不能及的。同步只能让调用者去轮询自己(情况2中),造成老张效率的低下。
所谓阻塞非阻塞,仅仅对于老张而言。立等的老张,阻塞;看电视的老张,非阻塞。情况1和情况3中老张就是阻塞的,媳妇喊他都不知道。虽然3中响水壶是异步的,可对于立等的老张没有太大的意义。所以一般异步是配合非阻塞使用的,这样才能发挥异步的效用。
上面这个小故事还是有点问题,但基本可以说明问题了。
响应,一定是对一个事件、一个信号(诸如此类的描述)产生了反应。响水壶的响应是什么呢?水温达到一定程度,水壶的反应是会响。水壶响了,声音传递给老张,老张的反应是去关水壶。
再看普通水壶,水温达到一定程度,水壶没有反应,水的反应是冒气泡,冒水雾。只是这个信号不太容易传递,要跑过来看,所以老张只能以轮训的方式来办事情,没法跑到一边等通知。
对于两个水壶而言,烧水都是阻塞的,水没烧完就干不了其他的事情(比如说拿来砸胡桃???)
ok,回到我们的问题:为什么是异步?
回归到本质回答这个问题:响应式编程,本质上是对数据流或某种变化所作出的反应,但是这个变化什么时候发生是未知的,所以他是一种基于异步、回调的方式在处理问题。
怪圈:似乎绝大多数博客说着说着就开始讲解RxAndroid
正如副标题,在网上搜索到的绝大多数的博客都会说着说着就在教你如何使用RxAndroid。各位,请记住以下几点:
RxAndroid(或RxJava)是很优秀的响应式编程框架。
你并非一定需要使用RxAndroid。
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<File, Observable<File>>() {
@Override
public Observable<File> call(File file) {
return Observable.from(file.listFiles());
}
})
.filter(new Func1<File, Boolean>() {
@Override
public Boolean call(File file) {
return file.getName().endsWith(".png");
}
})
.map(new Func1<File, Bitmap>() {
@Override
public Bitmap call(File file) {
return getBitmapFromFile(file);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Bitmap>() {
@Override
public void call(Bitmap bitmap) {
imageCollectorView.addImage(bitmap);
}
});
ok,请允许我再问一个问题,如此简介的代码,您打算单独用一个类来放吗?
如果对于任何一个处理类似业务逻辑的rx代码段都使用类来放,可能类数量会爆炸,而且这些类的命名看起来会很奇葩。若不这样,您的业务实现类中将充斥诸如此类不精读不敢确定语义、容易被误修改、不容易测试的代码。面对这样的代码的时候只会是如履薄冰战战兢兢。
我是在反对使用RxAndroid吗?
No,我只是反对滥用Rx,我赞成对某些高度抽象的异步行为使用Rx构建具有语义性的框架代码,例如:编写MVVM分层框架。反对对任何业务细节都去做“一切皆流”的无脑工作。毕竟:业务是需要逐渐迭代发展的,对于有测试代码支撑的、同时有较强语义性的类,我们泛读代码就可以“闻弦歌而知雅意”,对于需要重构何处代码,修改何处逻辑心中有数,而不必将“流”再反转回“实际的相互关系”,再打乱,修改,再组织成流,再恶心下一次迭代,而且,最关键的是“你可能要从很多的流中找出这一个流”。
[转帖]浅谈响应式编程(Reactive Programming)的更多相关文章
- Unity基于响应式编程(Reactive programming)入门
系列目录 [Unity3D基础]让物体动起来①--基于UGUI的鼠标点击移动 [Unity3D基础]让物体动起来②--UGUI鼠标点击逐帧移动 时光煮雨 Unity3D让物体动起来③—UGUI DoT ...
- .Net中的反应式编程(Reactive Programming)
系列主题:基于消息的软件架构模型演变 一.反应式编程(Reactive Programming) 1.什么是反应式编程:反应式编程(Reactive programming)简称Rx,他是一个使用LI ...
- iOS开发之OC篇-响应式编程Reactive Cocoa
一.Reactive Cocoa 介绍 Reactive Cocoa 是 iOS 开发的一个 "重量级" 框架 高大上的概念:响应式编程 核心概念:信号 Signal 官方网站:h ...
- 浅谈响应式Web设计与实现思路
是否还在为你的应用程序适配PC端,移动端,平板而苦苦思索呢,是否在寻找如何一套代码适配多终端方式呢,是否希望快速上手实现你的跨终端应用程序呢,是的话,那就看过来吧,本文阐述响应式UI设计相关理论基础, ...
- 函数响应式编程(FRP)—基础概念篇
原文出处:http://ios.jobbole.com/86815/. 一函数响应式编程 说到函数响应式编程,就不得不提到函数式编程,他们俩有什么关系呢?今天我们就详细的解析一下他们的关系. 现在下面 ...
- [译] Swift 的响应式编程
原文 https://github.com/bboyfeiyu/iOS-tech-frontier/blob/master/issue-3/Swift的响应式编程.md 原文链接 : Reactiv ...
- 函数响应式编程(FRP)从入门到”放弃”——基础概念篇
前言 研究ReactiveCocoa一段时间了,是时候总结一下学到的一些知识了. 一.函数响应式编程 说道函数响应式编程,就不得不提到函数式编程,它们俩到底有什么关系呢?今天我们就详细的解析一下他们的 ...
- 响应式编程知多少 | Rx.NET 了解下
1. 引言 An API for asynchronous programming with observable streams. ReactiveX is a combination of the ...
- Rx.NET响应式编程
响应式编程 Rx.NET 了解下 1. 引言 An API for asynchronous programming with observable streams.ReactiveX is a co ...
随机推荐
- ZR#1008
ZR#1008 解法: 直接预处理出来执行完一个完整的串可以到达的位置,然后算出重复的次数直接乘在坐标上,最后处理一下余下的部分就行了. CODE: #include<iostream> ...
- select2多选设置select多选,select2取值和赋值
select2设置select多选,select2取值和赋值,作为筛选条件的时候,取值相对简单,把选中的id值转为字符串传给后端查询,查询之后会刷新页面,为了在下拉框中显示刚刚选中的值,就需要给sel ...
- 【TensorFlow官方文档】MNIST机器学习入门
MNIST是一个入门级的计算机视觉数据集,它包含各种手写数字图片:它也包含每一张图片对应的标签,告诉我们这个是数字几.比如,下面这四张图片的标签分别是5,0,4,1. 从一个很简单的数学模型开始:训练 ...
- Oracle语法 及 SQL题目(三)
目录 SQL题目六 第一个问题思路(查询酒类商品的总点击量) 第二个问题思路(查询每个类别所属商品的总点击量,并按降序排列) 第三个问题思路(查询所有类别中最热门的品种(点击量最高),并按点击量降顺序 ...
- UK Biobank专题
这个时代的生信,统计遗传,不懂或不会用这个数据库就说不过去了. 看看10年GWAS里是如何定位和评价UK biobank的: For the near future, the UK Biobank i ...
- Centos7修改为固定IP后 yum 出现could not retrieve mirrorlist
Centos7修改为固定IP后 yum 出现could not retrieve mirrorlist,发现yum源的域名无法解析 按照6,修改/etc/resovle.conf,新增域名解析服务器1 ...
- Mysql中 查询慢的 Sql语句的记录查找
Mysql中 查询慢的 Sql语句的记录查找 慢查询日志 slow_query_log,是用来记录查询比较慢的sql语句,通过查询日志来查找哪条sql语句比较慢,这样可以对比较慢的sql可以进行优化. ...
- SSA与ASS字幕
SSA字幕与ASS字幕 SSA全称SubStationAlpha,是由CSLow(又称Kotus)创建的一种字幕格式,用以实现比传统字幕诸如srt等格式更为复杂的功能.SSA目前的版本为v4.00.S ...
- RabbitMQ之Topic交换器模式开发
Topic交换器,即主题模式,进行规则匹配. 一.Provider 配置文件 spring.application.name=provider spring.rabbitmq.host=192.168 ...
- Office Tool Plus
https://otp.landian.vip/zh-cn/index.html 本软件支持Microsoft Office办公软件最新版本高速下载.卸载.修复.定制化安装.静默安装等诸多功能. 同时 ...