业务模块内的 MVC 和 MVVM 架构
目前, 唯品会中 MVC 和 MVVM 架构并存, 后期会偏重于 MVVM 架构的使用.
MVC 架构
Model: 程序中要操纵的实际对象的抽象, 为 Controller 提供经过抽象的业务数据, 供 Controller 调度
View: 视图, 负责界面的元素的展示
Controller: 控制器, 管理 View 的声明周期及子 view 的生成和组装, 负责 Model 和 View 之间的通信.
MVC 框架的优势:
1. 应用广泛, 几乎所有前端语言都有类似 MVC 的设计痕迹
2. 设计思想非常简洁, 学习成本很低, 新人上手非常容易.
MVC 框架的问题:
MVC 并没有对数据请求和处理逻辑代码应该放在哪一层做出明确地划分, 因此一旦页面逻辑或交互稍微复杂, Controller 就会变得很臃肿, 代码也就越来越难维护.
MVVM 架构
MVVM 框架是在 MVC 的基础上演化而来, MVVM 想要解决的问题是尽可能地减少 Controller 的任务.
Model: 程序中要操纵的实际对象的抽象
View(ViewController):MVVM 中的 View 不再是 UIView 的子类, 而变成了 UIViewController 的子类. 这里的 View 实际上就是 MVC 中剥离了处理呈现 View 逻辑部分的 Controller, 因此它仍然有各种 UIView 的属性, 仍然有 ViewController 的声明周期的各种方法, 但是这里的 Controller 不再负责数据的请求以及处理逻辑, 因此不再臃肿.
ViewModel:MVVM 中, ViewModel 代替了 MVC 中的 Controller 成为了协调者的角色, ViewModel 被 View(ViewController) 持有, 同时持有者 Model. 数据请求以及处理逻辑都放在 ViewModel 中, View(ViewController) 就瘦了下来.
MVVM 框架的优势:
1. View(ViewController) 通过对 ViewModel 中的数据进行绑定来更新界面, 不用通过逻辑或者条件判断来更新 view, 大大降低了复杂交互时出 bug 的几率.
2. View(ViewController) 中代码简洁, 后期的维护和优化比较容易.
MVVM 框架的问题:
学习成本比 MVC 高, 如果对 MVVM 的职责划分理解不透彻, 很容易导致 ViewModel 的存在形同虚设, 反而增加了维护的成本.
我们为什么要用 MVVM?
订单售后这个页面内容非常多, 而且里面的内容会变, 还可以收缩展开, 还会出现由接口请求成功或失败来控制某一部分的显示还是隐藏. 当你使用普通的 MVC 架构的时候, 你会发现, 在 controller 里的代码量非常惊人的, View 的计算也非常复杂, 当有一块内容要在中间展示的时候, 下面的所有的 View 的 Y 值都得重新计算. 显然, 维护成本是非常高的, 改动一个小点还可能会导致蝴蝶效应, 测试也要回归当前页面所有的用例.
那有没有好的办法来解决这些问题呢? 我只想在自己的小块里加功能, 当小块的内容高度变化了, 整个页面的布局高度跟着自己变化呢. 答案是有的, 那就是使用 MVVM 模式.
看下图的 UML 类图, 分析一下, 如下:
下面就 CollectionView 做说明, 每一个内容都是一个小块 Cell, 都有自己的 cellViewmodel, 整个控制器有一个大的 viewmodel, 包装所有的 cellViewmodel, 就这样构建一个页面.
1,itemCell 是小块 Cell, 里面主要是初始化 View, 更新 View 的数据, 需要返回 cell 的宽高
2,cellViewModel, 是 itemCell 的 ViewModel, 给 itemCell 提供数据, itemCell 的点击事件也是回调到 cellViewModel 中.
3,Cell1ViewModel 和 item1Cell 组成一个小块 Cell1
4,Cell2ViewModel 和 item2Cell 组成另一个小块 Cell2
5,ViewModel 网络请求拿到数据之后, 组装上面的小块 Cell1ViewModel, 小块 Cell2ViewModel, 通过方法 [ - (Class)cellClass ] 就可以拿到当前的 itemCell
6,ViewModel 中, 还通过 block 的方式, 对 Controller 回调绑定了事件, 比如 cell 的点击事件, 加载数据成功事件, 按钮点击事件等
例子
Demo 有两种处理方式, 一是通过继承基类, 重写基类的方法来实现; 二是通过协议, cell 使用 cellprotocol 协议, cellModel 使用 cellModelProtocol 协议.
使用方法
直接继承 MVVMBase 使用
新建一个控制器 VSDemoCollectionViewController, 继承于 VSMVVMCollectionViewController
新建一个该控制器的 ViewModel(VSDemoCollectionViewModel), 继承于 VSMVVMCollectionViewModel, 负责管理所有的 CellViewModel
新建一个 CellModel(VSDemoCollectionItemCellModel), 继承于 VSMVVMCollectionViewCellModel, 负责管理元素 Cell, 在方法 cellClass 中, 返回关联的 Cell(VSDemoCollectionItemCell)
新建一个 Cell(VSDemoCollectionItemCell), 继承于 VSMVVMCollectionViewCell, 需要重写 VSMVVMCollectionViewCell 中的方法, 返回该 cell 的高度.
页面很复杂, 需要重新步骤 3 和 4, 不断的拆分这个复杂的 Cell.
最后, 所有的 cellModel 都交由第 2 步的控制器的 ViewModel 整合加载.
源代码
代码 Demo 已经上传到 GitHub: https://github.com/jiangys/VSMVVM https://github.com/jiangys/VSMVVM
来源: https://www.cnblogs.com/jys509/p/13257669.html