剖析响应式编程的本质

基于Actor的响应式编程计划分为三部分,第一部分剖析响应式编程的本质思想,为大家介绍何谓响应式编程(Reactive Programming)。第二部分则结合两个案例来讲解如何在AKKA中实现响应式编程。第三部分则是这个主题的扩展,在介绍Reactive Manifesto的同时,介绍进行响应式编程更为主流的ReactiveX框架。

响应式编程(Reactive Programming)到底是什么?从名词定义来讲,中文的响应式并没有很好地展现Reactive的本意。响应这个词语是一个中性词,本身没有任何倾向。Reactive Programming强调的是“响应迅速”,响应用户的请求要如电光火石一般迅捷,做到一触即发。

传统的顺序编程采用每条指令依次执行的方式,倘若上一条指令没有执行结束,当前的线程就得等着,任你如何提升机器性能还是代码性能,如果本质不变,始终改变不了响应需要等待的现实。若要响应迅速,就得把顺序执行指令的方式换一换——同步换成异步,方法执行换做消息发送,于是乎,我们可以精简地定义:

响应式编程就是异步数据流编程。

这其实是一种编程范式,是编程理念的一种思想转型。因为采用响应式编程,我们就不再将软件要处理的业务视为对象,又或者函数,而是直接透析到本质:数据流(Data Stream)。

一言以蔽之:万事万物皆为流。

我这么说,可能有些绝对。响应式编程并非银弹,也非你手中四处寻找钉子来敲打的锤子。我们须得结合着实际的场景,考虑是否选择响应式编程这种范式。然而,如果我们局限在响应式编程的语境下,我们确乎可以视万事万物为流。

从函数式编程的角度来讲,一连串组合函数的调用,其实就是数据在流动。函数可以抽象地视为一种数据类型到另一种数据类型的转换。将各种形式的转换(map、flatMap、filter)穿起来,同时保证数据的不变性(Immutable),则数据就能非常可靠地在函数链条中流动,或者被分析,或者被转换,或者被过滤。

回到业务世界。我们几乎可以将所有业务处理流程都可以建模为数据流的形式。这种流动差不多可以归纳为:

Command -> CommandHandler -> Event -> EventHandler -> Command ...

这是一种颇有节奏感的“建模仪式”。按照CQRS的设计思想,任何业务都可以分解为两种形式的消息:Query与Command。Query模型相对简单,因为它本质上就是一个没有副作用的只读操作。执行Command本身是要改变业务对象值的,然而,如果我们将每次变更都视为是一种“状态的迁移”,然后利用事件去记录每次变更,就可以将可变转换为不变。如果熟悉git,就会发现git的版本管理与此建模思想不谋而合。无论是新增、修改还是删除代码,都可以视为是一次全新的提交。

当我们将编程的范式切换为“流(Stream)”时,我们欣喜地发现,这种方式可以在很大程度上确保数据是不变的。这就为并行开发创造了可能。

然而,普通的数据流编程范式并不能满足“响应式Reactive”的本初定义。我们需要响应迅速。如何才能做到?那就是要做到没有阻塞,这就是我们通常所说的异步工作方式。

因而,响应式编程的设计原则是:

  • 保持数据的不变性
  • 没有共享
  • 阻塞是有害的

这或许也可以视为是响应式编程的特征,恰好,这三条特征也是Actor模型拥有的。

那么,什么是Actor模型?溯源Actor模型,它由Carl Hewitt在1973年提出,之后在Erlang OTP(Open Telecom Platform)中被广泛应用在并发编程上。最初的Scala语言也实现了简单的Actor模型,但随着AKKA框架的推出,Scala放弃了自身的Actor,转而选择使用AKKA。

在《Scala并发编程》一书中,Aleksandar Prokopec形象地描述了Actor系统:

Actor系统模仿了人类的组织,如公司、政府和其他大型机构。在软件公司中,有许多需要以并发方式达成的目标。为了实现这些目标,数百或数千名员工一起努力工作,而且这些员工通常会被组织成一种层次结构。许多员工会为级别比他们低的员工分派工作。为了高效地工作和决策,员工们使用电子邮件进行通信。 当员工早上上班时,就会检查他的电子邮箱并对重要的消息做出回应。如果某封电子邮件非常重要,那么这个员工就必须立刻回复这封邮件。当员工忙着回复一封电子邮件时,可能会收到另一封电子邮件,而且后续的电子邮件都会进入他的电子邮箱中。只有当员工处理完成当前的电子邮件后,他才能继续处理下一封电子邮件。

在这个隐喻中,软件公司就相当于是一个ActorSystem,每位员工则是一个一个Actor。电子邮件是Actor之间彼此发送的消息(Message),一旦发送了消息,就不必等待收件人的回复,可以继续自己的工作,也就是说这种消息发送的方式是异步非阻塞的。Actor持有的MailBox正好借用了这里所谓的电子邮箱概念。

因而对于每个Actor而言:

  • 每个Actor都拥有独立的MailBox;
  • 接收到的消息皆为不可变对象,且完全独立;
  • 不管是tell消息还是ask消息,Actor执行消息的方式都是异步非阻塞的。

金风玉露一相逢,从某种意义上讲,Actor模型就是响应式编程苦苦追寻的良缘佳配。二者天生匹配,且Actor模型的分布式特性还能更好地加强响应式编程的响应与处理速度。

原文发布于微信公众号 - 逸言(YiYan_OneWord)

原文发表时间:2016-09-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java架构

一个两年的程序员,面5家斩获点我达,网易offer的面试总结总结

毕业到现在也近两年了,最近面试了阿里集团(菜鸟网络,蚂蚁金服),网易,滴滴,点我达,最终收到点我达,网易offer,蚂蚁金服二面挂掉,菜鸟网络一个月了还在流程中...

961
来自专栏HansBug's Lab

【作业】HansBug的前三次OO作业分析与小结

OO课程目前已经进行了三次的作业,容我在本文中做一点微小的工作。 第一次作业 第一次作业由于难度不大,所以笔者程序实际上写的也比较随意一些。(点击就送指导书~)...

3446
来自专栏做全栈攻城狮

电脑小白学习软件开发-C#语言基础之循环重点讲解,习题

本教程是基础教程,适合任何有志于学习软件开发的人。当然因为技术的连贯性,推荐按照顺序查看。

582
来自专栏申龙斌的程序人生

零基础学编程021:获取股票实时行情数据

春节期间重写了“笑来投资演练程序1.0版”这个程序,可以每个月自动更新几支股票的行情数据。程序的功能不复杂,但是编程新手想实现它仍有相当的困难。为了短时间内完成...

50012
来自专栏用户画像

1、根据SC数据库用SQL语句完成以下任务。

update SC set Grade=Grade+5 whereGrade<60;

632
来自专栏Java架构

一个三年Java工程师的面试总结

15年毕业到现在也近3年了,最近面试了阿里集团(菜鸟网络,蚂蚁金服)、网易、滴滴、点我达,最终收到点我达和网易offer,蚂蚁金服二面挂掉,菜鸟网络一个月了还在...

1253
来自专栏编程

老丁独家!前方高能,与“程序崩溃”的第一次邂逅!

本阶段课程适合2年级以上刚开始接触EV3机器人的同学们。 本篇请下载 LEGO Mindstorms教育版软件 有条件的话,请为孩子添置一套EV3套装,让课程内...

1839
来自专栏牛客网

Java面经:小米暑期实习+秋招真题分享一面 1小时7分钟总结一面二面三面总结

秋招结束,总结了一下从寒假回来开始的实习生招聘和秋招面经,过来回馈一下牛客网。 上学期寒假回来就开始投简历,找人内推的小米,过几天后约时间面试,部门未知。 一面...

8836
来自专栏梧雨北辰的开发录

Python学习(1):入门与导学一、了解Python二、Python能做些什么三、Pthon特点四、Python的缺点五、Python之禅六、Python学习的相关资料

1736
来自专栏数据小魔方

R语言数据清洗实战——复杂数据结构与list解析

数据清洗从来都不是一件简单的事情! 使用httr包结合浏览器抓包工具进行网页数据抓取虽然非常方便,但是获取的数据后期处理工作量却非常庞大的。 因为大部分json...

3835

扫码关注云+社区