ReactiveCocoa 学习 - 1

通过函数式编程,减少状态的保存,来提高代码可读性,同时以支撑MVVM

2016-04-26 | 阅读

MVVM

MVVM实际上是 M V C VM,如下图所示,将臃肿的C的抽出一部分作为VM,而在MVVM中肯定还是有C存在的.而从Controller层,将 网络服务调用,模型对象,数据持久化等这些东西都放入ViewModel中.Model是从后台或者本地存储中获取的数据,到真正的View上显示需要做一些转换,而这层转换也放入了ViewModel中,即ViewModel中暴露出来的属性是直接可以放在View中显示的.

ViewModelViewController在一起,又是互相独立的.ViewController调用ViewModel,以通知操作发生,而ViewModel来处理数据,但是不以任何形式直接作用或通知ViewController.ViewController持有ViewModel,负责处理ViewModel中的变化.

ReactiveCocoa

ReactiveCocoa 是一套开源的基于Cocoa的FRP框架 .FRP的全称是Functional Reactive Programming,中文译作函数式响应式编程,是RP(Reactive Programm,响应式编程)的FP(Functional Programming,函数式编程)实现。说起来很拗口。太多的细节不多讨论,我们先关注下FRP的FP特征。

函数式编程

函数式编程,简单来说,就是多使用匿名函数,将逻辑处理过程,以一系列嵌套的函数调用来实现,以减少中间状态的存在。

简单举例,一个简单的表达式,(将表达式理解成一系列的逻辑处理流程):

(1 + 2) * 3 - 4

如果是传统的过程式编程,则会这样写:

a = 1 + 2;
b = a * 3;
c = b - 4;

而在函数式编程中,我们将运算过程(逻辑处理流程),定义为不同的函数,然后会写成:

result = subtract(multiply(add(1,2), 3), 4)

从这里,我们就可以看出一个特点,过程式编程会在运行中,将一步步操作的结果以状态的形式纪录下来,下一步操作是修改上一步操作的结果。 而在函数式编程中,上一步操作的结果会直接以参数的形式或者其它形式传递给下一步操作,不再本地保存一堆无用的中间状态,而是输入一个初始值,就返回一个相应的结果。中间状态会互相影响,过多的中间状态会降低代码可读性以及提高维护的难度。通过函数式编程,减少状态的存在,一个操作,一个流程,只由输入值来决定输出结果,不在运行过程中以来全局状态或者保存中间状态。 所以函数式编程的主要优点就在于 不保存中间状态,缺点的话,为了不保存这个中间状态,而在函数间传递,会增加函数的调用次数,而这样会在一定程度上降低效率。

函数式编程的其它优点:

  1. 代码简洁,开发快速。
  2. 接近自然语言,易于理解。
  3. 利于单元测试,和模块化组合。
  4. 易于并发编程

函数式编程,指尽量减少状态的保存,直接由输入得到结果,而不是在一些地方放置一堆的状态.即Model更新时,是直接作用于View,让View做出相应的显示,而不是保存一个状态,然后再通知View来获取这个状态.对于少量的状态,这样处理起来可能没问题,但是一旦状态多起来,管理就变得十分麻烦,难以调试.所以函数式编程,目的是 让相同的输入导出相同的输出,减少由于保存状态带来的影响.

响应式编程

响应式编程是一种面向数据流和变化传播的编程范式。这意味着可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。 例如,在命令式编程环境中,a:=b+c表示将表达式的结果赋给a,而之后改变b或c的值不会影响a。但在响应式编程中,a的值会随着b或c的更新而更新。

响应式编程对应的是命令式编程,命令式编程中,数据以状态的形式保存,通过命令来通知需要状态的对象来更新状态。iOS和UIKit在设计上是命令式的,如TableView的DataSource ,委托模式强制将状态保存在委托中,以在请求发生时,为TableView提供数据.

使用ReactiveCocoa的原因

数据的改变导致View的改变,现在我们常用的一般是命令式的编程,控制器去发动数据的改变,然后保存数据的状态,然后再去驱动View来加载最新的数据状态.

随着业务变得更加复杂,这种做法导致Controller上有一堆的状态数据,而这些状态数据错综复杂,互相影响,导致代码可读性较差,所以我们倾向于使用一种函数式编程的方式.数据修改后,直接设置View,而不是保存数据的状态,或者说将这步数据状态保存的操作抽离出来,不放在业务代码中,以提升代码的可读性,这就是使用ReactiveCocoa的原因.