浅谈响应式编程(Reactive Programming)

https://www.jianshu.com/p/1765f658200a

例子写的非常好呢. 
0.9312018.02.14 21:22:16字数 1877阅读 9816

这是告别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)的更多相关文章

  1. Unity基于响应式编程(Reactive programming)入门

    系列目录 [Unity3D基础]让物体动起来①--基于UGUI的鼠标点击移动 [Unity3D基础]让物体动起来②--UGUI鼠标点击逐帧移动 时光煮雨 Unity3D让物体动起来③—UGUI DoT ...

  2. .Net中的反应式编程(Reactive Programming)

    系列主题:基于消息的软件架构模型演变 一.反应式编程(Reactive Programming) 1.什么是反应式编程:反应式编程(Reactive programming)简称Rx,他是一个使用LI ...

  3. iOS开发之OC篇-响应式编程Reactive Cocoa

    一.Reactive Cocoa 介绍 Reactive Cocoa 是 iOS 开发的一个 "重量级" 框架 高大上的概念:响应式编程 核心概念:信号 Signal 官方网站:h ...

  4. 浅谈响应式Web设计与实现思路

    是否还在为你的应用程序适配PC端,移动端,平板而苦苦思索呢,是否在寻找如何一套代码适配多终端方式呢,是否希望快速上手实现你的跨终端应用程序呢,是的话,那就看过来吧,本文阐述响应式UI设计相关理论基础, ...

  5. 函数响应式编程(FRP)—基础概念篇

    原文出处:http://ios.jobbole.com/86815/. 一函数响应式编程 说到函数响应式编程,就不得不提到函数式编程,他们俩有什么关系呢?今天我们就详细的解析一下他们的关系. 现在下面 ...

  6. [译] Swift 的响应式编程

    原文  https://github.com/bboyfeiyu/iOS-tech-frontier/blob/master/issue-3/Swift的响应式编程.md 原文链接 : Reactiv ...

  7. 函数响应式编程(FRP)从入门到”放弃”——基础概念篇

    前言 研究ReactiveCocoa一段时间了,是时候总结一下学到的一些知识了. 一.函数响应式编程 说道函数响应式编程,就不得不提到函数式编程,它们俩到底有什么关系呢?今天我们就详细的解析一下他们的 ...

  8. 响应式编程知多少 | Rx.NET 了解下

    1. 引言 An API for asynchronous programming with observable streams. ReactiveX is a combination of the ...

  9. Rx.NET响应式编程

    响应式编程 Rx.NET 了解下 1. 引言 An API for asynchronous programming with observable streams.ReactiveX is a co ...

随机推荐

  1. Fiddler抓取https请求证书问题【转载】

    转载链接: https://www.cnblogs.com/liulinghua90/p/9109282.html

  2. 「SCOI2011」棘手的操作

    传送门 Description 有\(N\)个节点,标号从\(1\)到\(N\),这\(N\)个节点一开始相互不连通.第$ i\(个节点的初始权值为\)a_i$ ,接下来有如下一些操作: U x y ...

  3. T-MAX组--项目冲刺(第四天)

    THE FOURTH DAY 项目相关 作业相关 具体描述 所属班级 2019秋福大软件工程实践Z班 作业要求 团队作业第五次-项目冲刺 作业正文 T-MAX组--项目冲刺(第四天) 团队名称 T-M ...

  4. Ubuntu -- unknown error: Chrome failed to start: exited abnormally (Driver info: chromedriver=...)

    #添加沙盒模式 chrome_options.add_argument("--no-sandbox")

  5. 【内功修炼】"裁员潮",“中年危机”,该如何战胜你的焦虑

    "裁员"."中年危机"这些曾经看上去比较遥远的词汇,最近开始频繁出现在各种文章和新闻中,个人觉得这主要由两方面原因造成: 近两年,国内外经济形势严峻(更有经济学 ...

  6. SQL Server 2012 无人值守安装

    方法1,通过指定条个參数安装   setup.exe /Q /IACCEPTSQLSERVERLICENSETERMS /ACTION=install /PID=<validpid> /F ...

  7. Linux服务器下日志截取

    我们经常需要去Linux服务器上查看服务运行日志,但是有时候日志文件很大看起来很不方便,这个时候我们需要对日志进行切割筛选出自己需要的日志,比如查看某段时间内的日志,命令如下:   sed -n '/ ...

  8. 在input内添加小图标或文字(元/月)等

    文字: <td class="formValue"> <div class="input-group"> <input id=&q ...

  9. Qt编写气体安全管理系统10-数据导出

    一.前言 数据导出一般指导出到excel表格,可能有部分用户还需要导出到pdf,因为pdf基本上不可编辑,防止用户重新编辑导出的数据,excel可能绝大部分用过电脑的人都知道,广为流行,主要就是微软的 ...

  10. mysql存储过程中declare 和set 定义变量的区别

    declare为对变量进行声明,声明必须制定变量的数据类型,只能写在过程的前面set是对变量赋值,可以放在过程的任何地方对没有declare声明过的变量赋值,该变量必须以加上@号,否则会报错 DECL ...