TW洞见|也谈响应式编程
Posted 思特沃克
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TW洞见|也谈响应式编程相关的知识,希望对你有一定的参考价值。
今日洞见
文章作者来自ThoughtWorks:任晓君。封面图片来自网络。
本文所有内容,包括文字、图片和音视频资料,版权均属ThoughtWorks公司所有,任何媒体、网站或个人未经本网协议授权不得转载、链接、转贴或以其他方式复制发布/发表。已经本网协议授权的媒体、网站,在使用时必须注明"内容来源:ThoughtWorks洞见",并指定原文链接,违者本网将依法追究责任。
本文将会围绕reactive extension介绍reactive programming的起源,其要解决的问题。
最近几年,reactive programming这个词语的热度迅速提升,下面的 google trends的这个图表很能说明问题。
自从高级编程语言被发明以来,各种编程范式的编程语言层出不穷,命令式编程(如C)面向对象编程(如Java,Ruby),函数式编程(如Clojure, Scala,Haskell)都曾经或者正在软件开发领域占有一席之地。
上世纪九十年代前,命令式编程仍然在软件开发领域占有主导地位。随着软件规模的不断增大,面向对象编程以其封装性,可重用性受到开发者和组织的青睐。
随着摩尔定律的失效,单核CPU的计算能力几乎达到了极限,CPU进入了多核时代,程序员转而通过并发编程,分布式系统来应对越来越复杂的计算任务。
然而并发编程并不是银弹,做为一种基于共享内存的并发编程,多线程编程有常见的死锁,线程饥饿),race condition等问题,而且多线程bug的以其难以重现定位臭名昭著。
近年来逐渐火爆的functional programming以其提倡的:
函数是编程语言的一等公民(function as first-class citizen)
不可变量(immutable variable)
无副作用的函数(no side-effect/reference transparency)
可组合的函数(composable functions)
顺利地解决了因可变量mutabble variable被多个线程共享,修改等而导致可能的多线程的bug。
然而,functional programming就是现代的完美编程范式了么?远远不是。
即使使用了functional programming, 程序员总会需要处理异步任务或者事件,并且总有一些IO或者计算密集型的任务,这些任务可能还会阻塞其他活动线程,而且,处理异常,失败,线程任务之间的同步都比较困难而且容易出错。程序员需要不断地询问一个线程的运算结果(在Java中以Future<T>表示,T表示运算结果的类型)是否可用。我们来考虑一下下面两个例子:
有三个线程t1, t2, t3,他们的运算结果分别为f1, f2, f3。
有一个线程t4依赖于这三个线程的运行结果,而且每个线程都有有可能执行失败。
我们该如何编写线程t4的代码?
GUI程序中一次拖动操作中光标的位置就可被表示为Future<List<Position>>, (使用Future是因为这些Position的值是在未来的时间点生成的)。
如果我们希望在第一个Position可用时(拖动时间的开始位置)就能够在这Position所对应的位置画点,而不是等所有的Position都可用是一次性把光标的运行轨迹画出来。即我们希望程序能够尽快对输入进行响应。
即程序要及时,非阻塞地对输入响应。
上面的两个例子就是reactive programming尝试解决的问题,而Reactive Extension做为这个问题的答案,应运而生了。
Reactive Extension 这个概念最早出现在.net社区的Rx.net,一个提供处理异步事件的程序库,其核心概念是Observable,表示有限或者无限多个现在或者将来到达的事件。Observable提供了onNext,onError, onCompleted供开发者定制新元素到达,出现错误,或者流结束时的程序的行为。
并提供了List上类似的操作,如map,filter,reduce,大大降低了异步事件编程的复杂度。
因为这些概念是如此的强大,以至于很多编程语言,如java,ruby,javascript很快就有了各自的reactvie extension。
关于reactive extension的技术细节可以在我的这篇博客里找到。这个视频详细地介绍了为什么需要reactive extension,以及reactive extension的是如何被发明出来的。
Wikipedia上对reactive programming解释如下:
reactive programming is a programming paradigm oriented around data flows and the propagation of change.
举个例子,在命令式编程下,表达式a = b + c,a的值在这个表达式执行完毕之后就是确定的,即使b,c的值发生变化,a的值也不会改变。然而在响应式编程的语境下,a的值与b,c的值是绑定的,上述表达式其实建立的是a与b,c之间的一种依赖,a的值会随b和c的变化而变化。
我们称之为能够响应输入变化的事件(event)。
然而现在来看,上述定义已经不能囊括reactive programming的含义了。随着软件系统的非功能需求要求越来越高,reactive已不仅局限于响应事件(event)的传递,也表示程序能够响应负载(load),系统运行时出现的错误(failure)。
发布于2014年9月份的Reactive Manifesto以宣言的形式提供了能够满足这些需求的软件系统架构设计的指导原则。
在笔者看来,reactive programming可以从语言和架构两种层面上来理解,近年来层出不穷的各种语言的reactive extention就是语言层面的代表,而在架构层面上,也有遵循了reactive manifesto的类库(如akka)出现,笔者暂且称之为reactive architecture。
在后续的文章中,笔者将会带着大家理解一个reactive architecture是如何做到reactive的。
各类干货洞见
活动预告总结
以上是关于TW洞见|也谈响应式编程的主要内容,如果未能解决你的问题,请参考以下文章