MVC 真是一个神奇的"东西". 似乎每一个 GUI 应用都有其"亲戚": MVP, MVA...姑且称他们为 MV(X) 吧. 虽然他们都有 MV 开头, 但是实际又有所区别.
下文从几个角度去讨论他们的共性, 希望给 MV(X) 找到一个更高抽象中的统一.
越定义越难以定义
资料上对于 MV(X) 的描述是相对混乱的. 如果不满足于对 MV(X) 的简单定义, 深入去了解的话可以查到很多资料. 理解起来相信并不是太困难, 但要说准确定义, 这些资料却各有各的说法. 但是首先要明确的是, 他们都属于架构模式.
架构模式是一个通用的, 可重用的解决方案,用于在给定上下文中的软件体系结构中经常出现的问题, 架构模式与软件设计模式类似,但具有更广泛的范围. 简单说, MV(X) 是一个粒度较大的解决方案, 经常出现在 GUI 应用程序中.
MVC 诞生的原因
从事物诞生原因的角度去看待事物本身, 总是能得到最清晰的认识. MVC 诞生到现在将近50年了, 发明者将其描述为一种能够在人类心智模型和计算机数字模型之间建立连接的模型, 在开发操作大量数据集的GUI应用的时候, 该模型能够给出有效且通用的解决方案.
简单说, 在开发 GUI 应用上, 使用 MVC 是非常有效的.
为什么 ViewModel 会被发明出来?
我们一开始使用计算机解密情报, 现在我们用来叫外卖, 这是一个高度依赖计算机的时代. 在摩尔定律提供的廉价计算资源的基础上, 日益增进的业务复杂度迫使我们发明了面向对象技术, 显然, 这并不够.
据说Windows 10的代码行数约为70-80M, 数以千计的工程师为其贡献代码, 巨大的系统复杂度能被众多的工程师分解, 这是现代复杂系统得已构建的基础. 我们总是需要控制自己面对的复杂度:如果不是将其分解, 就是令其自然. 当然, 这是有代价的.
ViewModel 的概念源自于 Presentation Model. 当视图很复杂的时候, 在视图和模型之间建立联系也许不再那么容易, 如果把视图的"复杂"抽离并抽象, 虽然加重了管理代价, 但的确降低了复杂度. 如果计算资源足够廉价, 将 ViewModel 与 View 进行绑定, 虽然加重了性能负担, 但却能进一步降低复杂度.
可以说, 廉价的计算资源与复杂的业务需求, 以及人类对复杂度的控制为这些技术的发明提供了主要动力.
区别只是名字
从本质上看, MV(X)是恰到好处的职能分离. 职能分离降低了复杂度, 而恰到好处的职能分离则更为"自然". 若是把相关的行为都进行归类, 对行为的依赖进行梳理, 也许可以构建出清晰干净的结构, 但并不一定足够"自然". 对于 GUI 应用来说, 最自然的分离方式就是把代表本质的模型(Model) 与表现本质的视图(View) 进行分离.
Model 与 View 职责分离得越干净, 就越需要有人去干"脏活". 干净的 View 只关心图形绘制, 干净的 Model 只关心业务逻辑封装, 将两者进行关联是门"技术"活: 在不同的技术框架下, View 和 Model 的的关联可以是单向或双向, 直接或间接, 给其职能一个最为贴近的命名, 可以是 Controller(C), Presenter(P), Adapter(A)...
这重要吗? 并不是那么重要. 明确的分类能帮我们准确的认识与运用, 但也可能会把我们框死在定义中, 从更宽松的视角去认识也许更合适.
结语
如果事情足够简单, 一定能做得又快又好, 把MV(X) 看作是一个以降低复杂度为目的而发明的工具, 也许是一个比扣定义更合适的方式.
网友评论