公司iOS项目MVVM架构模式设计及分析MVVM+RAC的优缺点
概述
  这篇博客主要是介绍公司的iOS项目MVVM架构模式的设计及分析MVVM+RAC的优缺点。
MVC
Model : 实体模型
View : UI控件,负责View的绘制及用户的交互。
Controller : 业务逻辑、数据处理和UI处理
MVC, Model - View - Controller,一个很古老很经典的设计模式,拥有大概50年的历史。而MVC这个架构模式的最大优点就是其概念简单,易于理解,任何一个软件工程毕业的学生都应该在大学课程中学习过。但如果开发过程中使用不当,很可能使大量的代码集中在Controller之中,使Controller变得十分臃肿。
MVP
Model : 实体模型
View :UI控件,负责View的绘制及用户的交互。
Presenter : 负责完成View和Model之间的交互与业务逻辑。
MVP, Model - View - Presenter,其实就是将MVC中Controller换成Presenter,是MVC的一个变种。其目的是完全切断View和Model之间的联系,由Presenter充当桥梁对视图和模型进行解耦。
MVVM
Model : 实体模型。
View : UI控件,负责View的绘制及用户的交互。
ViewModel :负责View和Model之间的交互,业务逻辑等。
MVVM, Model - View - ViewModel, 一个从MVC模式中演化出来的设计模式。在iOS开发过程中,将原本在Controller中的业务逻辑、数据请求,数据处理 放到ViewModel中,从而有效地减少ViewController中的代码量,减轻ViewController的负担。同时将业务逻辑等放到ViewModel中也方便后期的测试与维护。
公司MVVM架构模式的设计
  因为MVVM架构模式的方便测试、维护,复用性高和低耦合等特性,所以公司的项目采用MVVM的架构模式。同时在iOS客户端的开发过程中,我们使用了ReactiveCocoa来实现其绑定机制。
关于ReactiveCocoa
   ReactiveCocoa 简称RAC,是由GitHub开源的一个应用于iOS和OS X开发的新框架。集合了函数式编程和响应式编程,所以RAC也被称为函数响应式编程框架(FRP)。
   在开发过程中RAC解决了传统开发中状态之间依赖过多、Controller过于臃肿等问题。提供了统一的消息传递机制,降低了类与类之间的耦合度,提高了开发效率。具体使用方法可以参看GitHub中ReactiveCocoa的详细文档。
公司某项目目录结构
项目中的目录结构:
1 | - 第三方sdk(应该用Frameworks):主要存放一些暂不支持CocoaPods的第三方库。 |
  每种语言发展到一定阶段都会出现相应的依赖管理工具,例如Java的Maven,nodejs的npm,而iOS依赖管理工具是CocoaPods。CocoaPods的出现为我们节省了集成、管理第三方库的时间,所以公司的项目同样使用了CocoaPods管理第三方库。
  而在数据结构方面我们使用了Google的Protocol Buffer(简称:Protobuf)。而Protobuf是google公司内部的混合语言数据标准,是一种轻便高效的结构化数据存储格式,可以用于结构化数据的序列化。
  使用时需要先配置开发环境,具体可以查看之前写的一篇博客《Mac 下配置protobuf(3.2.0)开发环境》。如果使用的是Proto2可以查看另篇博客《ProtocolBuffer for Objective-C 运行环境配置及使用》。
MVVM + RAC的优缺点
   RAC和MVVM上面已经介绍过。现在越来越多的项目已经开始使用MVVM的架构模式,同时RAC已经成为MVVM的标配。由上图动画可以看出,对于一个简单的MVC架构的iOS应用,很容易调整到MVVM的。
  当然在我们享受函数响应式编程框架带来的便捷的同时,也需要承受其带来缺点。但随着自己能力的提高,这些所谓的缺点也会渐渐消失。如果有兴趣也可以查看美团点评技术团队关于RAC的研究,相信你定会有所收获。
- 优点:
  1. 方便测试与维护。将业务逻辑、网络请求,数据处理放到ViewModel中便于后期单元测试、维护。
  2. 低耦合。双向绑定,View可以根据Model的改变而进行修改,一个ViewModel可以绑定到不同的View上。
  3. 复用性高。可以将一些视图逻辑放到ViewModel中,让很多View重用此视图逻辑等。
- 缺点:
  1. ReactiveCocoa学习成本较高。大部分人对MVVM不太熟悉,基于绑定机制进行编程需要一定的学习成本才能较好的上手。
  2. 数据绑定使Debug更困难。数据绑定会使程序异常传到其他位置,由上图可以看出,当View上发现bug时,有可能是ViewModel造成的,也可能是Model造成的。