blogWithMarkdown icon indicating copy to clipboard operation
blogWithMarkdown copied to clipboard

Principles of Reactive Programming

Open spacewander opened this issue 10 years ago • 0 comments

三月底的时候,要去实习的公司就已经早早地确定下来了。这么一来,我有了一大段时间可以自由支配,可以学点有趣的东西,在毕业之前多多拓展自己的视野。

抱着这样的念头,外加一时心血来潮,我决定去跟一门MOOC课,看看传说中的MOOC课是什么样子。一阵东挑西选之后,我选中了这么课:Coursera上的《Principles of Reactive Programming》。当时之所以做出这样的选择,主要原因有三:

  1. 当时正好对并发程序开发感兴趣
  2. 这门课开课时间正好对得上
  3. 计算机类的课程,大部分不是简单的算法入门或者编程语言介绍,就是机器学习或数据挖掘之类偏学术的课程。适合我口味的课并不多。

当然啦,这么课还有一点加分项:开课的三位讲师都是大牛,包括scala的作者、ReactiveX的开发者以及Akka的scala版本的开发者。总之,让他们三个讲Reactive编程简直再适合不过了。

既然讲师都是scala背景的,这门课自然是以scala讲述。于是乎,我还得去学scala才能跟上老师的授课。由于报名的时候,离开课只剩一个星期,想学会scala是不可能了,所以在上课的同时,也需要继续完善scala的学习。

这门课给我带来的第一份收获是对scala这门语言的认识。

虽然以后我恐怕不会用scala来开发自己的项目(主要是因为编译耗时太长,拖慢了开发效率),但是scala这门语言也是相当有趣的。它就像是c++一样,同时包含了多项编程范式。你可以把函数式风格和面向对象风格杂糅在一起。不过我最为看中的是,scala就像其他现代静态编程语言一样,把类型推导和匿名函数双剑合璧,大大拓展了语言的表达能力。除了之外,scala还有许多语法糖,比如mixin、操作符重载和时间字面量,具体可以看看 Ruby VS Scala。总之,scala是一门非常华丽的编程语言,具有许多让编程语言控兴奋不已的特性。当然,这么多特性的后果,是复杂到有时语法错误连IDE都发现不了,以及吊打c++的编译耗时。

Ok,该回到主题了,继续聊聊这门课。

课程一开始是介绍函数式编程的一些概念,比如map和flatmap等等。接着开始引入一些具有Reactive风格的概念,比如Signal。然后逐渐进入主题,开始出现两对基友:

One Many
Synchronous T/Try[T] Iterable[T]
Asynchronous Future[T] Observable[T]

把同步的类型T/Try[T]包装起来,就是异步的Future[T]。持有一个Future,等同于持有一个结果(或者包含了该结果的Try类型)。 把同步的类型Iterable[T]包装起来,就是异步的Observable[T]。持有一个Observable[T],就能遍历对应的Iterable[T],不管迭代出来的值是刚刚新鲜出炉的,还是返回原有对象的一部分。

于是我们可以这样设计异步的API,把返回的单个值/可迭代的容器依对应的Future/Observable包装起来,交给用户去决定取值的时间。这样,发生阻塞的决定权由调用函数交给了调用方(因为把执行交给了后台的线程,甚至可以同时执行多个函数,充分发挥并行化的威力)。

按Reactive字面上的意思,就是依据外界的刺激进行响应。所以获取到了外界的刺激,下面就应该作出对应的响应了。

第一部分学到的函数式编程概念在这里就用得上了。我们可以把函数和外界的刺激绑定在一起,当刺激传递过来时,依据刺激的类型(成功还是失败)或者值,调用对应的函数进行处理。scala的模式匹配在这里派上了大用场:

  val pageSubscription: Subscription = pages.observeOn(eventScheduler) subscribe {
      x => {
        x match {
          case Failure(e) => editorpane.text = e.getMessage
          case success: Success[String] => editorpane.text = success.get
        }
     }
  }

外加scala自带和Reactive框架提供的onErrormapflattenmerge等api,基本上对数据的处理就像流一样,你可以随心所欲地发布一条新的支流,也可以合并现有的支流。总之,把刺激逐个处理的想法已经过时了。现在你需要把它们放入流水线上,或者更准确地说,放到神经系统中,让它们按照预先设定的情况去走对应的分支。比起之前的做法,新的做法更加清晰明了。

最后的几周是关于Akka框架的。Akka是一个基于Actor的并发系统。基于Actor的系统基本上都差不多,基本包括下面几条规则:

  1. Actor分为几种不同的状态。
  2. 每个Actor都有一个地址,可以给别的Actor发信息
  3. 信息也分为几种。你可以在信息中夹带数据
  4. 根据收到的信息的不同,Actor可以进行对应的处理,也许会进入新的的状态。

这也是一种Reactive Programming,跟前面的那种不一样的是,这次我们把数据变成了信息,把处理函数变成了状态。感觉这种形式要比前面那种要好写。

于是乎7周的课程就这么有惊无险地过去了。期间有赶deadline的紧张,也有对作业无从下手的焦虑;有顿悟新想法的快乐,也有排除万难拿到10/10的激动。最后终于得到了一个优秀的成绩,给这段MOOC之旅划上美满的句号。

最后的最后,顺便晒一下结课的证书: https://www.coursera.org/maestro/api/certificate/get_certificate?course_id=974748

spacewander avatar Jun 28 '15 07:06 spacewander