响应式编程漫谈

编程范式的演进

自从高级编程语言被发明以来,各种编程范式的编程语言层出不穷,命令式编程、面向对象编程、函数式编程都曾经或者正在软件开发领域占有一席之地。

上世纪九十年代前,命令式编程仍然在软件开发领域占有主导地位。随着软件规模的不断增大,面向对象编程以其封装性、可重用性受到开发者和组织的青睐。

随着摩尔定律的失效,单核CPU的计算能力几乎达到了极限,CPU进入多核时代,程序员转而通过并发编程,分布式系统来应对越来越复杂的计算任务。然而并发编程并不是银弹,做为一种基于共享内存的并发编程,多线程编程常有的死锁、线程饥渴、竞争条件等问题,而且多线程bug以其难以重现定位而臭名昭著。

今年来逐渐火爆的函数式编程以其提倡的:

  • 函数是编程语言的一等公民(function as first-class citizen)
  • 不可变量(immutable variable)
  • 无副作用的函数(no side-effect/reference transparency)
  • 可组合的函数(composable functions)

顺利地解决了因可变量mutable variable被多个线程共享、修改等而导致可能的多线程的bug。

然而,函数式编程就是现代的完美的编程范式了么?远远不是。
即使使用了函数式编程,程序员总会需要处理异步任务或者事件,并且总有一些IO或者计算密集型的任务,这些任务可能还会阻塞其他活动线程,而且处理异常、失败、线程任务之间的同步都比较困难而且容易出错。程序员需要不断地询问一个线程的运算结果是否可用,另外我们希望程序能够响应及时,这时候响应式编程应运而生。

响应式编程

跟面向对象编程或函数式编程一样,响应式编程也是一种编程范式,响应式编程是一种通过异步和数据流来构建事物关系的编程模型。
举个例子:
A = B + C
A被赋予了B和C相加的值,如果我们改变B或C的值,A的值并不会随之改变。而如果我们运用一种机制,当B或C的值发生变化的时候,A也随之变化,这样就实现了“响应式”。

响应式编程的提出目的就是简化类似的操作,因此它在用户界面编程领域以及基于实时系统的动画方面都有广泛运用,另一方面在处理嵌套回调的异步事件,复杂的列表过滤和变换的时候也有良好的表现。

目前来看,响应式编程至少有这些好处:

  • 在业务层面实现代码逻辑分离,方便后期维护和扩展
  • 极大提高程序响应速度,充分发掘CPU的能力
  • 帮助开发者提高代码的抽象能力和充分理解业务逻辑
  • Rx丰富的操作符会帮助我们极大的简化代码逻辑

谈到响应式编程,不得不提Reactive Extensions,这个概念最早是起源于微软.NET社区,目前已经有好多语言对其进行了实现,如RxJava、RxSwift、RxJS等等,微软的官方的解释:

Reactive Extensions(Rx) is a library for composing asynchronous and event-based
programs using observable sequences and LINQ-style query operators.

简单地说就是利用Observable和LINQ风格的基于事件驱动的编程扩展库,它是响应式编程的一种实现,用于解决异步事件流的一种解决方案,就是利用它可以很好地控制事件流的异步操作,将事件的发生和对事件的响应进行解耦,可以让开发者不再关心复杂的线程处理、锁等并发相关问题。

其核心概念是Observable,表示有限或者无限多个现在或者将来到达的事件。Observable提供了onNext,onError, onCompleted供开发者定制新元素到达,出现错误,或者流结束时的程序的行为。
并提供了List上类似的操作,如map,filter,reduce,大大降低了异步事件编程的复杂度。

在响应式编程中有两个设计模式被应用得比较广泛,观察者和迭代器。
观察者模式定义了对象间的一种一对多的依赖关系,当一个对象状态发生变化时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布订阅模式、模型视图模式、源监听器模式或从属者模式
观察者可以分为两种:push和pul

1. push,就是被监听者将消息推送出去,进而触发监听者的相应事件,响应式编程一般采用这种模式
2. pull,就是监听者主动从被监听者处获取数据

迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露内部的表示

函数响应式编程

函数响应式编程(FRP)是指主要利用函数式编程的思想和方法(函数、高阶函数)来支持的响应式编程。
FRP将输入分为两个基础部分:行为和事件。行为是随时间连续变化的数据,而事件则是基于离散的时间序列。

后续我会开始以RxSwift的这方面继续深入iOS针对响应式编程的实践。