传统的MVC模式
在MVC下,所有对象都被归类为模型、视图和控制器。
模型保存数据
视图向用户呈现交互界面
视图控制器调解模型和视图之间的交互。
视图通知控制器任何用户交互。
视图控制器更新模型以反映状态的变化。
模型(通常通过 Key-Value-Observation)通知任何控制器他们需要对其视图执行的更新。
Model
模型对象通常非常非常简单。通常,它们是Core Data托管对象。
根据 Apple 的说法(理想状态),模型包含数据和操作该数据的逻辑。
在实践中(现实状态),模型通常非常薄,模型逻辑都被写在控制器中。
View
视图(通常)是 UIKit 组件或程序员定义的 UIKit 组件集合。
这些是 .xib 或 Storyboard 中的部分:应用程序的可视化和可交互组件,按钮、标签。
视图不应直接引用模型,而应仅通过 IBAction 事件引用控制器。
与视图本身无关的业务逻辑在那里没有业务。
Controller
控制器是应用程序的==“粘合代码”==所在的地方:
- 调解模型和视图之间所有交互的代码。
- 控制器负责管理他们拥有的视图的视图层次结构。
- 它们响应视图加载、出现、消失等。
- 处理模型中的模型逻辑和在视图中的业务逻辑
因此,我们看到MVC是有很多缺点的,归纳起来大致有:
MVC的缺点
- 控制器中大量代码
- 缺少网络逻辑
- 可测试性差
- 管理的模糊定义
1. 控制器臃肿
这个就很明显了,大量逻辑代码都放在控制器上,导致控制器臃肿
2. 缺少网络逻辑
如果将其放入模型对象中,因为网络调用应该异步完成,因此如果网络请求比拥有它的模型寿命更长,那么它就会变得复杂。
视图中❌🚫❎
控制器,这也是一个坏主意,因为它会导致我们的 Massive View Controller 问题(第一个缺点)。
3. 可测试性差
4. 管理的模糊定义
视图控制器管理视图层次结构,视图控制器有一个“视图”属性,可以通过 IBOutlets 访问该视图的任何子视图。
当您有许多outlets时,这不能很好地扩展,并且在某些时候,您可能最好使用子视图控制器来帮助管理所有子视图。
那个点在哪里?什么时候分解事情变得有益?验证用户输入的业务逻辑属于控制器还是模型?
基于MVC存在的缺点,MVVM是否可以解决呢?
MVVM
在MVVM下,视图和视图控制器正式连接起来;我们将他们视为一体
视图仍然没有对模型的引用,但控制器也没有。相反,它们引用视图模型。
View Model是放置用户输入验证逻辑、视图表示逻辑、网络请求启动和其他杂项代码的绝佳位置。
View Model绝对不要包含View
不要在视图模型中 #import UIKit.h
对于MVVM,需要一些绑定机制,这样 View Model 就能在背后的 Model 改变时更新自身的属性。
此外,一旦 View Model 上的 Model 发生改变,那 View 的属性也需要更新。Model 的改变应该级联向下通过 View Model 进入 View。
ViewModel持有Model
针对MVC的四个大的缺点,MVVM的解决途径:
- 将视图表示逻辑放入View Model,则控制器变得不那么臃肿
- 网络请求就放在ViewModel
- 使用 MVVM 编写的 iOS 应用程序具有高度的可测试性;
- 很多逻辑代码,都可以放在View Model当中
使用 MVVM 的结果,是代码总量略有增加,但代码复杂度整体下降。
使用 ReactiveCocoa 是将所有移动部件粘合在一起的好方法。
参考资料:
MVVM介绍
适用于 iOS 的模型-视图-视图模型