本文将以 Objective-C 语言为媒介,介绍 MVVM 设计模式的概念、特点及其在 iOS 开发当中的应用。
MVVM 是什么?
MVVM(Model-View-ViewModel)为一种常用的软件设计模式,是由 Martin Fowler 提出的 PM(Presentation Model)设计模式的变体,而 PM 来源于 MVC。John Gossman 于2005年在其博客中正式发表了 MVVM 设计模式。
MVVM 的关系大致可以描述为:
这张图是在说:
- Model 可以用通知的方式与 ViewModel 通讯。
- ViewModel 可以更新 Model。
- ViewModel 和 View 之间是双向绑定关系,即一方发生变动后,另一方也会发生变动。
- Model 无法与 View 直接通讯。
“M”
M = Model,即模型(与 MVC 中的 “M” 相同)。
- M 中包含了数据模型,相比 MVC 而言,应当尽量减少数据组装的逻辑,使其变得更纯粹(VM 可以做这些)。
- M 无法引用 VM。
“V”
V = View + Controller,在 iOS 中,”V” 并不是单纯的 View,而是和 Controller 结合在一起,二者密不可分,合称为 “V”。
- V 负责着界面的展示、响应用户的操作行为、响应 ViewModel 的变化。
- V 不应该包含过多的业务逻辑(给 MVC 中的 C 减负),这些应当交由 ViewModel 去做。
- V 无法引用 M,而是应该引用 VM。
“VM”
VM = ViewModel,即视图模型,是 MVVM 中的核心部分,相当于 MVP 设计模式中的”P”,不同的是,VM 与 V 之间是双向绑定的关系,而 P 和 V 不是。
- VM 负责封装绝大部分业务逻辑、网络请求、缓存及视图显示逻辑。
- VM 无法引用 V,否则导致耦合。
- VM 可以引用 M。
总结
优点
- 低耦合:V 与 M 分开,解放了 V 中的 Controller(相对 MVC),使得 V、M 可以独立修改和开发。
- 可重用:一套 VM 可以绑定不同的 V。
- 可测试:针对页面的测试代码可以针对 VM 来写。
缺点
- 高复杂度:相对 MVC、MVP 而言,双向绑定使得代码在掌控的时候有一定的难度和复杂度,如果控制不当,很可能出现像 MVC 中 Massive ViewController 的情况。更麻烦的是,V 中的 Controller 和 VM 都有可能变得难以维护。
- debug 困难:当页面上出现一个问题的时候,V 和 VM 都有可能出问题,这样就对定位 bug 产生了一定的阻碍。尤其是,业务逻辑非常复杂时,这样的窘况会更加严重。
注意点
- MVVM 配合某种绑定机制效果卓越(比如 ReactiveCocoa)。
- 利用 MVVM 设计模式之前一定要思路清晰,否则可能会写出难以维护的代码。
- MVVM 兼容 MVC,要对这两者灵活运用,适合的才是最好的。
结语
各界对于 MVVM 的评价一直很高,甚至有人认为 MVVM 的存在可以完全代替 MVC,但我觉得这是不对的,VM 的存在使得 MVVM 的使用并没有比 MVC 简单多少。MVC 直到现在仍作为苹果推荐的 iOS 应用开发设计模式,必然有其相应的道理。这也就说明,设计模式没有明确的优劣之分,适合当前业务场景的,就是好的。在开发过程中,不盲从,不一味地选择更高级的设计模式,合理分析业务逻辑和项目架构,选择与之契合的设计模式,才是最重要的。