目前iOS开发应用一般是基于Swift语言的,但有些功能也会涉及到objective-c。关于MVC的争论已经有很多,对此我的观点是:对于iOS开发中的绝大部分场景来说,MVC本身是没有问题的,你认为的MVC的问题,一定是你自己理解的问题。
iOS中的MVC和MVP
简而言之,MVP是View驱动的,View层持有一个对应Presenter的引用,View上的交互事件首先会调用Presenter提供的接口,然后Presenter调用Model提供的方法取得数据,最后Presenter将取得的数据传递到View上展示.
MVC则是由Controller驱动的,Controller持有View,并响应View上的交互事件,根据交互调用不同的Model方法取得反馈数据,再将数据传递给View展示.
我的理解是,MVP是用户视角:所见即View.MVC则是程序员视角:I control everyone.
理解MVC和MVP的差别困惑的地方在于, UIViewController 到底是属于C(P)层还是V层呢?下面将分别具体分析一下这两种观点.
观点一:UIViewController的归属--->View
如果把UIViewController视为V层,即上面MVP示意图中的Passive View,那么UIViewController将只负责View布局相关逻辑,不涉及任何与Model层的交互!!
不涉及任何与Model层的交互!!
不涉及任何与Model层的交互!!
所有的业务逻辑交互通过UIViewController持有的Presenter与Model间的调用来完成.
观点二:UIViewController的归属--->Controller
那如果把UIViewController视为C层,从MVC设计理念上来说,C层不会负责具体View的布局及展示逻辑,但是由于iOS中UIViewController的特殊设计,导致很多开发者直接就在UIViewController包含了很多具体布局相关的代码,更可怕的情况是不止是View的初始化,包括网络请求及具体业务处理也被包含到UIViewController中,这也许就是有人戏称MVC为:MassiveViewController的原因.
Model,DataInfo以及对胖瘦Model的争议
Model和DataInfo的差异
MVC架构思想中更倾向于Model是一个Layer,而不是一个Object(Java或Android中的bean).
所以这里的DataInfo我将其定义为一个DTO(Data Transfer Objec),更简单的来说,就是一个数据结构,跟我们在学校学习C语言时写的一个student结构体基本是一个意思.
我的理解是,Model是用来处理业务逻辑的,可视为传统开发三层架构中的BLL(Bussiness Logic Layer)和DAL(Data Access Layer)的合体,负责所有的具体业务.比如,对一个包含安全认证的App,你可能需要一个AuthModel来负责所有的认证逻辑以及认证信息的本地持久化.这样,Controller中只需要调用AuthModel提供的接口便能完成相应安全认证功能,职责分明.
Model中的一些方法的产出DTO,用来更新View.例如UserModel会去查询用户信息,然后将服务器返回的用户信息转换成一个本地的UserInfo,将这个UserInfo传递给View进行展示.
因此业界关于胖瘦Model的争议,我更多的理解是对于DataInfo是否需要提供涉及到业务的扩展功能的争议.了解更多实战项目中的情况,可以点击:ios视频教程
(http://www.maiziedu.com/course/ios/)
业务场景举例
举例一个业务场景,一个用户信息View上需要展示用户性别,一般来说服务器只会在返回的用户信息中包含一个sex字段(这里用0代表女性,1代表男性),需要使用的时候可能需要使用if语句进行判断然后输出不同的性别文字或图片.
从个人习惯上来说,很多开发者会将服务器返回的用户信息转换成一个本地的UserInfo DTO,然后将这个DTO传递给要对应需要展示的View,然后在View中进行输出判断.
当然,开发者可能会使用现在很流行的一些字典转模型框架(YYModel,MJextension等),也可以使用这些框架提供的配置接口在转换时就实现这种输出逻辑的转换,或者直接在UerInfo sex属性的getter方法中进行转换后输出.
不管怎样,只要在DataInfo这个层级上做了类似的这些转换,那么业务逻辑就已经侵入了DTO的定义.
一种解决思路
但是,这种场景几乎又是不可避免的,如何解决呢? 被误解的 MVC 和被神化的 MVVM 提出了一种借鉴MVVM的解决思路,具体做法就是将 ViewController 给 View 传递数据这个过程,抽象成构造 ViewModel 的过程.这样抽象之后,View 只接受 ViewModel,而 Controller 只需要传递 ViewModel 这么一行代码。而另外构造 ViewModel 的过程,我们就可以移动到另外的类中了.
在我看来,这样ViewModel层其实只是把上文中对DataInfo的扩展单独提炼了出来.这样就将View层完全与业务逻辑完全隔离开.
通过对比可以发现MVC已经可以满足iOS开发重构的基本要求,下篇文章中我们将举实例来说明这一问题。