iOS - MVC、MVP、MVVM
一、MVC
MVC 模式,即 Model-View-Controller。它是苹果公司官方推荐的 App 开发架构,也是一般开发者最先遇到、最经典的架构。
在 MVC 模式下,App 的组成可以分为三部分:
-
Model 层
:负责数据的持久化存储以及读取操作。 -
View 层
:负责视图数据的展示和交互。 -
Controller 层
:充当中介者,负责连接model 层
和view 层
。它将数据从model 层
传递到view 层
,同时将view 层
的交互传递到model 层
从而改变模型存储的数据。
Controller
是同时持有 View
跟 Model
的。
工作逻辑
- 当
View
发生交互事件时,会通过action
通知到Controller
,Controller
收到之后会去更新Model 层
的数据。 - 当
Model 层
的数据发生变化时,也会通知Controller 层
,之后会去更新View 层
。 - 可以看出,
View 层
跟Model 层
之间的通信都是依赖Controller 层
的,Controller 层
相当于中介者,同时协调着View 层
跟Model 层
。
优点
- 代码总量少。基本上,MVC 大量的逻辑和视图代码都集中在
ViewController 层
,Model 层
只是实现简单的数据存储,View 层
主要负责视图数据的展示和交互。 - 简单易懂。MVC 的设计模式可以让开发者很容易熟悉以及上手。
缺点
MVC 的缺点也很明显,大量的代码都集中在了 Controller层
。
- 代码过于集中。
ViewController 层
集合了视图的交互、视图的更新、布局、Model
数据的获取以及更新、网络请求等业务逻辑等大量的代码。 - 难以进行测试。大量的代码都堆积在了
ViewController 层
,高度耦合难以测试。 -
Model 层
过于简单。相比ViewController
的庞大代码,Model 层
只是定义几个属性在 Objective-C 的.m 实现文件中,更是几乎看不到代码。 - 网络请求逻辑无从安放。网络层放在
Model
中,网络请求一般是异步调用的,那如果网络请求的周期比Model
对象的生命周期还要长,那么就会使Model 层
的逻辑变得很复杂,若是将网络层放在ViewController
中,则耦合进一步加剧,以上缺点更会被放大。
二、MVP
MVP 模式的提出旨在解决 MVC 模式下 Controller 层
过于臃肿的问题,那么在MVP 模式下,会将 Controller层
的处理视图交互、发起网络请求更新 Model
数据以及更新视图 View
等一部分的业务逻辑抽离出来,减轻了 Controller 层
的负担。
MVP 模式是在 MVC 模式上衍生出了一个 Presenter 层
。
-
View 层
:这里的View层是包含View
以及Controller
的。主要负责视图的布局以及一部分的视图交互。 -
Model 层
:依然是负责数据的持久化存储以及读取。 -
Presenter 层
:负责接收来自View 层
的交互,并更新数据到Model 层
,当Model 层
数据变更时,负责通知View 层
更新视图。
工作逻辑
-
View 层
和Controller 层
都持有presenter 层
,而视图交互逻辑主要在presenter 层
,那么内部实现应该是View 层
将视图交互通知到presenter 层
,但是本身View 层
创建出的视图是被addSubView
进Controller 层
的根视图的,所以Controller 层
又会持有View 层
,那么另一种实现可以是:Controller 层
作为View 层
的代理,View 层
将处理视图交互的操作定义在协议里,将交互事件传递给Controller 层
,而Controller 层
本身持有presenter 层
,那么就调用presenter 层
实现的对于视图交互的方法。 - 要注意的是,
Controller 层
始终是核心层,它负责对于各个层主要的连接以及管理。
简单理一下用户交互的事件传递流程:
用户点击 View
视图 -> View
视图触发交互事件 -> 交互事件传递代理 Controller 层
-> Controller 层
调用 Presenter 层
实现好的交互操作 -> 发起网络请求更新持有的 model
数据 -> model 层
更新完毕之后通过代理或者通知到 Presenter 层
-> Presenter 层
再通过代理或通知通知到 Controller 层
或者 View 层
。
优点
相比于 MVC,减轻了 Controller 层
的负担,耦合度大大降低。
缺点
view
的所有交互都要传给 Presenter
处理,从而一旦功能增加了,View
的代码和 Presenter
的代码都会增加,相比于 MVC 在 ViewController
一个文件里面直接解决,MVP 的总代码量可能会翻倍,这样 App 的维护成本和文件都会增大。因此在 MVC 的基础上又衍生出了一种新的模式 MVVM。
三、MVVM
MVVM 模式是基于 MVC 模式的,在 MVC 的基础上分离出业务处理的逻辑到 ViewModel 层
。

在 View 层
跟 View Model 层
之间是双向的,但这不是相互持有的关系,这是一种类似于通知的方法,当 View
的数据发生变化会自动通知到 View Model
,当 View Model
的数据发生变化,也会自动通知到 View
,所以总的来说,MVVM 模式就是在 MVP 模式上新增了双向绑定。
目前主流的双向绑定方案主要有 RAC 以及 KVO
。
View/Controller
持有 View Model
,View Model
持有 Model
,那说明 View Model
的职责在于分担 Controller 层
的视图交互、网络请求、更新 Model
模型数据等的业务逻辑。
尽管在 MVVM 模式下,没有明确指出 Controller 层
的指责划分,但是我们仍然是将 Controller 层
充当 Manager
的身份,管理各个层以及将业务逻辑分配到 View Model 层
。
优点
相比于 MVP 模式,代码量大大减少。
缺点
利用 RAC 实现双向绑定需要引入第三方响应式框架,而且因为属性观察环环相扣,调用栈变大,Debug 起来会比较痛苦。