InfoQ 在 ETE 大会上对 Android 工程师 Jake Wharton 的采访

  • Michael Redlich
  • Rays

2017 年 6 月 22 日

话题:JavaDevOps语言 & 开发架构文化 & 方法

ETE 2017(用于企业的新兴技术,Emerging Technologies for the Enterprise)大会上,Square 的 Android 工程师 Jake Wharton 作了名为“使用 RxJava 管理响应式世界”(Managing the Reactive World with RxJava)的报告。

报告的中心主题是“除非整个系统可以同步地建模,否则一旦存在一个异步数据源,就会破坏整个指令式编程”。Wharton 解释说,一旦引入了异步数据源,指令式编程方式就开始坍塌。状态管理的重担是落在开发人员身上的,而非落在可简化开发的软件库上。他在报告中使用了RxJava例子展示了这一理念。他比较了基础源(Source)Observable<T>Flowable<T>、这些源的观察(Observe)方法,以及一些可操作数据或发射(Emission)的操作符。在报告最后进行总结时,他简要地探讨了 Java 9 和JEP 266中新引入的“Flow”类,其中封装了支持响应式“发布 - 订阅”框架的接口。

在 ETE 大会上,Wharton 向 InfoQ 介绍了他在 Square 的工作情况,以及他对响应式系统、RxJava 和 Kotlin 的理解。

InfoQ:您已 Square 工作多久了?当前职位是什么?

Wharton:我在 Square 工作了五年。

我参与Square Cash应用项目。它是一个 P2P 支付应用,可实现向朋友或家庭的转账。我供职于其中的 Android Mobile 团队,该团队主要构建 Android App。相比于名气更大的 Square Register 产品,Android Mobile 是一个相对较小的团队,只有三个人。我的主要工作聚焦于架构、基础设施和支持应用的软件库,目标是支持团队中的另两位开发人员高速地构建新的显示和特性,并解决如何构建的问题,以避免在 App 中陷入或碰上扩展性或序列化问题。我的目标是解决每一处枯燥的工作,使得产品本身总能以很快的速度推进。

InfoQ:很多人是通过零售终端系统(POS,Point-Of-Sale)业务而熟悉 Square 的。Square 还提供哪些产品或服务?

Wharton:除了 Square Cash,POS 基本上只是我们所有产品的冰山一角。Square 聚焦于商家,提供运行业务相关的所有产品。我们所瞄准的是使用 POS App 进行销售的各种个体零售商,从适当规模的餐馆到多单位业务。这些用户的需求不仅是一个可以刷卡的 App。就此我们还提供了一些衍生产品,例如雇员管理、安排预约和发票跟踪等。对于那些业务越做越大的用户,这些产品提供了辅助 POS 的功能。我们的理念是,如果当用户还是小型企业甚至是个体企业时就开始使用 Square,那么随着用户业务的成长和扩大,他们会移动到线上、移动零售地点、具有多个零售网点、雇佣员工,以及更多事情,我们希望用户依然使用我们所提供的生态系统。因为我们正在提供所有适用的产品,并更紧密地集成在一起,力图为用户提供最好的业务管理体验,避免业务管理变成一项令人乏味和世俗的任务。我们正在尝试提供多种适合用户的产品。

InfoQ:与其它的 POS 系统相比,Square 的产品具有哪些独特之处?

Wharton:现在每个人的口袋中都有一台计算机,我们已准备好迎接这一事实。对于用户在做的很多事情,我们都提供了可在移动电话上完成的功能,无论是使用 App 还是访问 Web 网站。我并非说我们的很多竞争者是传统的,而是说他们所构建的产品是用于十到十五年前的大型企业。这种做法在那个年代是合理的,因为人们并不会随身携带智能手机四处转悠。用户必须为这些软件厂商所提供的定制硬件支付大笔费用,而这些软件厂商却并没有提供深入用户业务的真正定制的、真正丰富的在线服务。Square 是一个高度移动化并以数据为第一位的企业,力图为用户提供所有可能的功能,这可以通过用户已有的 iPad,也可以通过当前已相对便宜的硬件实现。用户要开始采用移动端的支付业务,Square 就会免费提供给用户一些硬件,无需用户支付任何费用。这样用户基本上无需任何投资就可以做到移动支付。由于 Square 降低了业务入门的门槛,并且实现了移动端优先以及数据第一位,使得所有业务在线提供给用户,用户可以通过这样的方式使用移动电话、电脑等日常用品控制业务,并获取对业务的洞察力。另一方面,Square 面向的是一个传统上仍未得到开发的市场。银行及那些创建 POS 的企业所面向的是大型零售商店和大型连锁餐馆,这会为它们的投资带来很好的收益。但是还存在着整个尚未开发的零售商市场,其中包括小型的家庭经营商店、个人出售农产品以及手工艺制作者。这就是为什么你去其它地方购买咖啡时,会希望能看到 Square 的 POS 硬件,因为上面所说的市场中是只支付现金的。

InfoQ:RxJava 1.x 和 RxJava 2 间的主要差别是什么?

Wharton:现在具有两个主要类型的响应式数据源,这是 RxJava 1 和 RxJava 2 间的最大差别。存在这两个类型的原因在于,其中一个类型允许背压(Back Pressure),而另一个则不允许背压。在 RxJava 1 中,每个响应式类型的可观察对象(Observable)将暴露背压(即提供可放缓的功能),但事实上并非每个源都喜欢这样。因此有时你试图去放缓一个响应式源,它将会抛出一个异常。在 RxJava 2 中分离了这两种类型,因此现在我们知道类型系统中存在一个具备被可放缓功能的源,而另一个源则不具备。另一个主要挑战是,现在已有多家企业共同努力去标准化响应式软件库的 API,这被称为“Reactive Streams”。RxJava 2 原生地实现了这些接口,并暴露自身为符合 Reactive Streams 的实现。这是一个改进软件库内部架构的机会,降低了一些在先前的 RxJava 1 架构中已发现的开销。因此 RxJava 2 更快,兼容性更好。现在类型系统对数据源的进一步行为提供了更多的保证。

InfoQ:除 Netflix 之外,还有哪些企业正在使用响应式系统?

Wharton:Netflix 无疑是最大的响应式系统用户,正是由它联合发起了最初的 RxJava 1 实现,而且给出 RxJava 1 设计与实现的主要贡献者都曾供职于 Netflix。据我所知,Lightbend 也极大地推动了响应式。其 Akka 产品在传统上被认为是一个 Actor 系统,但是它同时也是 Reactive Streams 的一个兼容实现。除此以外,在ReactiveX网站还上列出了一些企业。在 Andorid 领域,响应式的确已在客户应用中被大量采用。当前各大企业在构建 App 时都使用了 RxJava。在服务器端,由于使用了很多墨守成规的软件库,因此无法看到像在 Android 上那样的快速转变。

Netflix 是响应式的最大使用者。其所构建的大量开源产品和软件库都是构建于 RxJava 之上的。Netflix 具有大量的内容,并提供了大量的如何使用这一模式构建系统的博客帖子。因此 Netflix 无疑是我所看见的最大使用者。

InfoQ:您是怎么看待响应式编程和 Reactive Streams?未来五年内 RxJava 将如何演化?

Wharton:当前在 JVM 端,Java 9 引入了与 Reactive Streams 项目所创建接口兼容的接口。在我看来,由于 Reactive Streams 已是 JDK 的组成部分,它将会在服务器端得到更广泛的采用。当然,对于被称作“Flow”的新 API,还应给出它的实现,因为当前尚未有这样的实现。它本质上只是一种 JDK 中的接口,而非一种具体的实现。因此,我们仍需要类似于 RxJava 和 Spring 的Project Reactor这样的软件库去实现它们。由于响应式已存在于 JDK 中,我们可能会看到大量这样的非常基础的服务器软件库(例如 Spring 和Netty)基于响应式构建自身的 API,使得这些 API 以这种一致的 Reactive Streams 方式暴露。此外,对于 Android 客户端,响应式是一种资源受限的环境,并且看上去 RxJava 2 无疑是手边最好用的,因为未来的 RxJava 和 Project Reactor 版本非常有可能是依赖于 Java 9 的。至少最近五年内,Java 9 将会在 Android 上大展宏图,并且实际上处于野生发展状态,我们可以开始使用它。可能除了软件库开始采用 RxJava 2 之外,我们将看不到更多的整体进展。

InfoQ:对于那些学习响应式编程和 RxJava 的开发人员,您推荐的第一步是什么?

Wharton:事实上,新版本的 Spring 已原生地实现了 Reactive Streams,其大量文档已经更新,文档中给出了如何使用 Spring API 响应式地构建服务器。对于服务器开发人员,这是个很好的出发点,从中可以看到一些构建和操作工作的实际实现。对于客户端和 Android 开发人员,现已有大量的可用内容,其中可以查看业内人士的演讲,查阅 App 的开源例子。这的确是最好的出发点,并且应是初学者确实必须去点击查看的。初学者应尽可能地观看更多的幻灯,尽可能地读取更多的文档,直到他们开始实践,了解响应式背后的机制,并掌握组件间相互交互的方式。一旦开发人员能从传统的命令式编程转向基于推送的响应式方式,并且真正地开始以新方式思考问题,就会得到一种“不过如此”的感觉。但是在此之前,如果没有尝试去构建并操作这些 API,我们的确只能局限于自己的理解之中。

推荐一两本可用的书。Netflix 的最早期开发人员Ben Christensen做了大量 RxJava 的最初工作。他参与撰写了一本书,并于数月前出版面世了。书中提供了很多入门内容,有助于读者构建一种思考问题方式的框架。在我看来,有很多的文档资料都并未做到这一点。这本书值得一读。

InfoQ:您是否愿意向我们的读者介绍一下您自己、您的工作,或是其它一些我们没有提及的方面吗?

Wharton:在我看来,最有意思的莫过于看到Kotlin会得到更广泛采用。Kotlin 实际上与响应式编程关联得很好,因为它允许对一个无论是否为 Null 的值建模,很显然这是一个经常发生的事情。Kotlin 还具有大量与 RxJava 工作很好的语言原语。举个例子,它允许我们使用密封类(Sealed Classes)层级结构,这本质上是一个抽象类,而后是对类的多种实现,不再需要实现额外的子类。这是非常重要的,因为这将允许开发人员对一些类型建模,这些类型可具有来自于用户接口的事件,例如可以是点击了一个按钮,还可以是用户按下了键盘上的回车键。两者可以是同一类型的子类,Kotlin 语言不仅允许开发人员使用简洁的语法定义这样的子类,并且提供了非常便于使用的when操作符。when操作符类似于 Java 中的switch,但是不同于switch之处在于when并非必须要给出一个默认的case语句,因为编译器可以证明这两个事件已经正在处理,并且将不存在其它具有该类型子类的事件。when也会实现类似于智能转换(cast)的功能。当执行对每个事件的 case 语句块时,它自动地将事件转换为这一类型。因此,对于所有事情必须流经同一管道的应用,如果要在这样的应用中构建 Reactive Streams,倾向于使用单一类型,之后再使用子类型表示不同的数据位。在将 Kotlin 这一语言和 RxJava 或其它任何的响应式库混合一起时,让语言使开发人员回归依照句法定义类型,以及依照句法从开发人员自身的下一次回调中拉取回类型,这种做法无疑具有很大的好处。

InfoQ:看上去近期 Kotlin 的发展势头很好。

Wharton:正类似于我们在 RxJava 中所经历的,这是 Android 移动开发快速地引入了新技术的另一个实例。现在 Kotlin 更为成熟了,我们将会在服务器端开发和已有的软件库中更多地看到它。无论出于何种原因,这些软件库需要更多的时间去采用这类更新的语言和新软件库。因此,很高兴能看到 Kotlin 得到了更多的关注。此外,Kotlin 非常关注自身的完全兼容性,并具有非常好的工具,这正是大量其它的 JVM 语言过去曾缺失的。

编者按:

自 2008 年以来,Michael Redlich 一直是 ETE 大会的积极参与者,先期作为参会者和演讲者,近期自 2013 年以来,担任 ETE 大会指导委员会成员。

查看英文原文: Jake Wharton, Android Engineer at Square, Speaks to InfoQ at ETE

JavaDevOps语言 & 开发架构文化 & 方法