[转帖]浅谈响应式编程(Reactive Programming)

浅谈响应式编程(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分层框架。反对对任何业务细节都去做“一切皆流”的无脑工作。毕竟:业务是需要逐渐迭代发展的,对于有测试代码支撑的、同时有较强语义性的类,我们泛读代码就可以“闻弦歌而知雅意”,对于需要重构何处代码,修改何处逻辑心中有数,而不必将“流”再反转回“实际的相互关系”,再打乱,修改,再组织成流,再恶心下一次迭代,而且,最关键的是“你可能要从很多的流中找出这一个流”。

原文地址:https://www.cnblogs.com/jinanxiaolaohu/p/11691624.html

时间: 2024-10-21 14:51:16

[转帖]浅谈响应式编程(Reactive Programming)的相关文章

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

系列目录 [Unity3D基础]让物体动起来①--基于UGUI的鼠标点击移动 [Unity3D基础]让物体动起来②--UGUI鼠标点击逐帧移动 时光煮雨 Unity3D让物体动起来③—UGUI DoTween&Unity Native2D实现 时光煮雨 Unity3D实现2D人物动画① UGUI&Native2D序列帧动画 时光煮雨 Unity3D实现2D人物动画② Unity2D 动画系统&资源效率 背景 前有慕容小匹夫的一篇<解构C#游戏框架uFrame兼谈游戏架构设计&

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

目录 系列主题:基于消息的软件架构模型演变 系列主题:基于消息的软件架构模型演变 一.反应式编程(Reactive Programming) 1.什么是反应式编程:反应式编程(Reactive programming)简称Rx,他是一个使用LINQ风格编写基于观察者模式的异步编程模型.简单点说Rx = Observables + LINQ + Schedulers. 2.为什么会产生这种风格的编程模型?我在本系列文章开始的时候说过一个使用事件的例子: 1 2 3 4 5 6 7 8 9 var 

IOS开发之OC篇-响应式编程Reactive Cocoa

一.Reactive Cocoa 介绍 Reactive Cocoa 是 iOS 开发的一个 "重量级" 框架 高大上的概念:响应式编程 核心概念:信号 Signal 官方网站:https://github.com/ReactiveCocoa/ReactiveCocoa 二.相关概念 1> 响应式编程 举个栗子,在一般程序开发时  a = b + c , 赋值之后 b 或者 c 的值变化后,a 的值不会跟着变化, 如果使用响应式编程,目标就是,如果 b 或者 c 的数值发生变化,

浅谈响应式布局

响应式布局是Ethan Marcotte在2010年5月份提出的一个概念,简而言之,就是一个网站能够兼容多个终端——而不是为每个终端做一个特定的版本.这个概念是为解决移动互联网浏览而诞生的. 最近几年来,越来越多的智能移动设备( mobile, tablet device )加入到互联网中来,移动互联网不再是独立的小网络了,而是成为了 Internet 的重要组成部分.响应式网络设计 ( RWD / AWD)的出现,目的是为移动设备提供更好的体验,并且整合从桌面到手机的各种屏幕尺寸和分辨率,用技

浅谈响应式网页设计

技术的革新带动了设计行业的的迅猛发展,这使得设计师和开发者有了更广阔的的探索天地.而网页设计也越发不再那么循规蹈矩,许多团队和公司都做了很多思考和创意.所以在我们适应着现代设计潮流的同时,不妨也来看看现阶段网页设计大致的趋势和风格吧.我不敢大言不惭的说这就是当下网页设计的趋势,这只是本人对当下网页设计做出的一些小总结.希望这样的归类总结能给你带来更多的思路和想法. 响应式网页设计 现在越来越多用户都拥有多种终端:台式机,笔记本,平板电脑,手机,能够适应不同尺寸显示屏的网页是现在的潮流,甚至是未来

[译] Swift 的响应式编程

原文  https://github.com/bboyfeiyu/iOS-tech-frontier/blob/master/issue-3/Swift的响应式编程.md 原文链接 : Reactive Swift 原文作者 : Agnes Vasarhelyi 译文出自 : 开发技术前线 www.devtf.cn 译者 :Mr.Simple 校对者:Lollypo 状态 : 完成 让我们首先回到Apple刚推出Objective-C的继任者-Swift的时候,那真是一个非比寻常的时刻. Sir

响应式编程(Reactive Programming)(Rx)介绍

很明显你是有兴趣学习这种被称作响应式编程的新技术才来看这篇文章的. 学习响应式编程是很困难的一个过程,特别是在缺乏优秀资料的前提下.刚开始学习时,我试过去找一些教程,并找到了为数不多的实用教程,但是它们都流于表面,从没有围绕响应式编程构建起一个完整的知识体系.库的文档往往也无法帮助你去了解它的函数.不信的话可以看一下这个: 通过合并元素的指针,将每一个可观察的元素序列放射到一个新的可观察的序列中,然后将多个可观察的序列中的一个转换成一个只从最近的可观察序列中产生值得可观察的序列. 天啊. 我看过

Reactive Cocoa 响应式编程开发实例讲解-中篇

上一篇文章作为开门篇讲述了Cocoa Reactive概述. 这里我们详细介绍一下CocoaReative在代码中的应用. 网上好多blog有人形容CocoaReative 中 signals是插座或者水龙头,感觉不是很好理解.我举个更贴近生活的,用电话订菜(餐馆是Signals,电话订阅是SubScriberNext). 1.概述 Create一个Signal我们视为是一个支持电话订餐的餐馆,他们有很多菜,油盐酱醋就更不用说,当一个电话打进来首先,这个Signal就开始执行,等菜做好了,菜馆要

响应式编程(Reactive programming)

响应式编程是指确保程序对事件或输入做出响应的做法.在这一节,我们将专注于图形界面方面的响应式编程,图形界面总量响应式的.然而,其他网格的编程也需要考虑响应式编程,例如,运行在服务器上的程序总是需要保持对输入作出响应,即使是在它处理其他需要长时间运行的任务期间.我们将在第十一章实现聊天服务器时,会看到在服务器编程方面也要用到这里讨论的一些方法. 大多数图形界面库使用事件循环去处理绘制图形界面,以及与用户之间的交互,就是说,一个线程既要负责绘制图形界面,也要处理其上的所有事件,我们称这种线程为图形界