序言
年年岁岁花相似, 岁岁年年人不同
很久很久以前
MVC 模式以低耦合性高重用性可维护性等优点, 使得原本复杂的代码与界面的交互变得简单清晰明了开发者可以把更多的精力放在前端界面的设计上, 而不用绞尽脑汁去思考究竟应该如何使界面得到同步既减轻了设计压力, 又能极大提高用户体验感
然而随着时间的推移以及技术的发展, 传统的 MVC 模式已经不适合当下的 iOS 开发了先让我们来复习一下 iOS 中的 MVC 模式吧!
MVC 架构模式
在 iOS 开发中, MVC(Model View Controller)是构建 iOS App 的标准模式在 MVC 下, 所有的对象被归类为一个 Model, 一个 View, 和一个 ControllerModel 持有数据, View 显示与用户交互的界面, 而 ViewController 调解 Model 和 View 之间的交互
现在, MVC 依然是目前主流客户端编程框架然而, 在 MVC 模式中, 厚重的 Controller 无以立足的网络逻辑和较差的可测试性已经成为该模式无可避免的问题了
厚重的 Controller
由于大量的代码被放进 view controller, 导致他们变的相当臃肿网络数据的请求及后续处理, 本地数据库操作, 以及一些带有工具性质辅助方法都加大了 MassiveViewController 的产生
遗失的网络逻辑
苹果使用的 MVC 的定义上说, 所有的对象都可以被归类为一个 model, 一个 view 或是一个 controller 那么要把网络的代码放在哪里呢?
显然, 不应该把网络请求放在 view 中若把它放在 model 对象里, 网络调用应该使用异步, 可是这样的话如果一个网络请求比它持有的 model 生命周期更长, 事情就会变得复杂若是放在 contoller 里面, 也会加剧厚重 controller 的问题
较差的可测试性
由于 View Controller 混合了视图处理逻辑和业务逻辑, 分离这些成分的单元测试成了一个艰巨的任务
为了避免和解决上述问题的产生, 于是就从 MVC 引申出来一种维护性较强耦合性低的新的架构 MVVM(Model View View-Mode),MVVM 正式规范了视图和控制器紧耦合的性质, 并引入新的组件 MVVM 主要目的是为了分离视图 (View) 和模型(Model)
MVVM 模式
MVVM 是 Model-View-ViewModel 的简写, 最早于 2005 年被微软的 WPF 和 Silverlight 的架构师 John Gossman 提出
Model: 和 MVC 中的 model 保持一致, 用于处理数据逻辑
View: 由 MVC 中的 view 和 controller 组成, 负责 UI 的展示, 绑定 viewModel 中的属性, 触发 viewModel 中的命令以及呈现由 viewModel 提供的数据
View-Model: 它的职责之一就是作为一个表现视图显示自身所需数据的静态模型, 它是从 MVC 的 controller 中抽取出来的展示逻辑, 负责从 model 中获取 view 所需的数据, 转换成 view 可以展示的数据, 并暴露公开的属性和命令供 view 进行绑定
在 MVVM 实现中, 利用 RAC 来优雅的实现 view 和 viewModel 两者之间的数据绑定(同步)
MVVM 优点
1. 低耦合视图 (View) 可以独立于 Model 变化和修改, 一个 ViewModel 可以绑定到不同的 "View" 上, 当 View 变化的时候 Model 可以不变, 当 Model 变化的时候 View 也可以不变
2. 可重用性你可以把一些视图逻辑放在一个 ViewModel 里面, 让很多 view 重用这段视图逻辑
3. 独立开发开发人员可以专注于业务逻辑和数据的开发(ViewModel), 设计人员可以专注于页面设计, 使用 Expression Blend 可以很容易设计界面并生成 xml 代码
4. 可测试界面素来是比较难于测试的, 而现在测试可以针对 ViewModel 来写
MVP 模式
MVP 是由 MVC 演变而来的, 它的 Presenter 根本不用关心 ViewController 的生命周期, 所以在 Presenter 里面几乎没有涉及到 UI 的代码, 我们所有的 UI 处理全部放到了 UIViewController 里面, 这样的话很符合设计模式中的单一职责
在 MVP 中, View 和 Model 之间是不存在引用和依赖的
下面分享一个 MVP 架构模式的简单案例
新建下面的类
在 MVPContoller 中对三个角色进行关联
创建属性
controller 类需要关联三个角色, 因此需要在该类中创建三个角色的属性
对三个角色进行初始化设置
分别创建三个角色, MVPView 要添加到 Controller 上显示这个案例就是为了将 Model 的内容显示到 view 中所以这里提前给 model 设置好内容调用 presenter 的 printTask 方法将两者关联起来
model 中存储需要的数据, 定义内容属性
此处跟 mvc 不同之处就是给 view 传递的是一个字符串而不是一个 model 因为 view 与 model 在 mvp 架构是无关联的
在 MVPView.h 中创建展示 view 的方法体
在 MVPView.m 文件中添加按钮
初始化按钮, 让 model 的内容显示在 label 上
presenter.h 创建一个方法
这个是业务逻辑的入口
在 MVP 模式中, 所有的耦合都存在与 Presenter 之中, 所以 Presenter 需要有 View 和 Model 的存在
将两者通过 Presenter 联系起来
Prensenter 的作用就是调用 view 并把 model 的内容传递给它
到程序入口处调用 MVPController
如此一来, 一个简单的 MVP 案例搭建完毕
面试题
1 在 MVC 模式中, 如何解决 controller 层的臃肿问题?
将网络请求抽象到单独的类中
将界面的拼装抽象到专门的类中
构造 ViewModel
这样抽象之后, View 只接受 ViewModel, 而 Controller 只需要传递 ViewModel 这么一行代码而另外构造 ViewModel 的过程, 我们就可以移动到另外的类中了
专门构造存储类
2MVC 和 MVVM 的区别
MVVM 是对胖模型进行的拆分, 其本质是给控制器减负, 将一些弱业务逻辑放到 VM 中处理
MVC 是一切设计的基础, 所有新的设计模式都是基于 MVC 进行的改进
参考链接:
- https://juejin.im/post/59de301cf265da4310475f2c
- https://www.jianshu.com/p/db8400e1d40e
- https://www.jianshu.com/p/79591e226d8c
来源: http://www.jianshu.com/p/61f34db5d905