MVC、MVP、MVVM
前言
这篇文章简单介绍MVC、MVP和MVVM三种架构,并配上一个简单的Swift demo来区分MVC和MVVM两种架构。
MVC
传统MVC
下图是传统结构MVC,可以看到这种结构是紧耦合的,不推荐使用。
苹果的MVC
如下图,这是苹果MVC架构的愿景,Controller作为View和Model的中介,这样它们就解耦了。
各层的职责如下所示:
- Model: 数据层,负责数据的处理和获取的数据接口层。
- View: 展示层(GUI),对于 iOS 来说所有以 UI 开头的类基本都属于这层。
- Controller: 控制器层,它是 Model 和 View 之间的胶水或者说是中间人。一般来说,当用户对 View 有操作时它负责去修改相应 Model;当 Model 的值发生变化时它负责去更新对应 View。
如上图所示,M和View应该是完全隔离的,由C作为中间人来负责二者的交互,同时三者是完全独立分开的,这样可以保证M和V的可测试性和复用性。
MVC在iOS中的实现
由于Apple的规范,一个界面的呈现都需要构建一个viewcontroller,而每个viewcontroller都带有一个根view,这就导致C和V紧密耦合在一起构成了iOS里面的C层,这明显违背了MVC的初衷。实际结构如下图。
根据苹果对MVC架构规范的描述,原文戳这里,viewcontroller其实是view和controller的组合,目的就是为了提高开发效率,简化操作。但这样也会导致一个问题,就是View层的代码全堆到了VC,比如VC中构建View,View的显示逻辑处理等等。
MVC各层功能
controller层(VC)
- 生成view,然后组装view
- 响应View的事件和作为view的代理
- 调用model的数据获取接口,拿到返回数据,处理加工,渲染到view显示
- 处理view的生命周期
- 处理界面之间的跳转
model层
- 业务逻辑封装
- 提供数据接口给controller使用
- 数据持久化存储和读取
- 作为数据模型存储数据
view层
- 界面元素搭建,动画效果,数据展示,
- 接受用户操作并反馈视觉效果
关于Model层,这里有一段文章引用说明了真正的Model层实际不应该只有几个结构和属性,应该有的是数据的业务逻辑。
MVP
结构如下图。
MVC中没有对业务逻辑和业务展示进行区分,MVP就是针对这一点进行的优化,它将业务逻辑和业务展示做了一层隔离。M和V功能不变, 原来的C现在只负责布局, 而所有的业务逻辑全都转移到了P层。P层处理完了业务逻辑,如果要更改view的显示,那么可以通过回调来实现,这样可以减轻耦合,MVP从视图层中分离了行为(事件响应)和状态(属性,用于数据展示),它创建了一个视图的抽象,也就是presenter层,而视图就是P层的『渲染』结果。P层中包含所有的视图渲染需要的动态信息,包括视图的内容(text、color)、组件是否启用(enable),除此之外还会将一些方法暴露给视图用于某些事件的响应。
MVP通信过程
- 当视图接收到来自用户的事件时,会将事件转交给 Presenter 进行处理;
- 被动的视图实现presenter的代理,当需要更新视图时 Presenter回调代理来更新视图的内容,这样让presenter专注于业务逻辑,view专注于显示逻辑
- Presenter 负责对模型进行操作和更新,在需要时取出其中存储的信息
- 当模型层改变时,可以将改变的信息发送给观察者 Presenter
MVVM
MVVM由三个部分组成,也就是 Model、View 和 ViewModel;其中视图模型(ViewModel)其实就是 MVP 模式中的P,在 MVVM 中叫做VM,架构图如下。
MVVM相对于MVP做的改进就是对VM/P和view做了双向的数据和命令绑定,利用Binder机制使得Model和View可以状态同步。
具体实例看MVC与MVP/MVVM的实现对比
可以看到项目中,MVVM比MVC多了一个ViewModel层,这是两者的不同,我们先来看看相同的Model和ViewController,两者除了命名不同其他的都相同,所以以下只展示一种。
Model
ViewController
fetchData部分写的内容是模拟网络请求数据,代码如下图。
fetchData
接下来让我们看到MVC中的View层
MVCView
可以看到在这里对业务的显示和业务的逻辑处理都放在了View层。
我们反观MVVM架构中,加入了一个ViewModel,它对业务逻辑部分抽象出了一个类,代码如下。
最后我们在View中,只用处理业务展示部分即可,代码如下。
以上就是MVC、MVP、MVVM的简要介绍。