MVC / MVVM / MVP / MV*,前端开发的学习或早或晚地都会接触到这几个名词,接触到这些的同学大致知道这些就是将你代码里面的数据(Model),看到的东西(View),和控制(Controller)独立分开的设计架构,使得 UI 更容易变化和更容易进行单元测试,噢?这不就是 Mvc 吗?那其他几个是什么?还有诸如 Angularjs 是现在最健壮的 Mvc 的说法,有种种的迷惑和误解,很多人对这些只是有模糊的概念,翻看网上的各种文章和博客,对其的解释也是东一句西一句,让人一头雾水。
那么看这里就对了,这篇文章就是用来给大家捋清楚这几个傻傻分不清楚的名词。
就这么简单,下面我们一个个分开仔细将:
MVC ( Model-View-Controller )
MVC 源自职能分化和规划的思想与目的,这不是这种思想的开始,但是是一个很好的尝试与起点。
MVC 的模型如下:
一般的流程就是,在 View 触发事件,然后 Controller 处理了业务,然后触发了数据更新,然后就更新了 Model 数据反馈到 View ,最后 View 更新。
在 MVC 模式里面 Controller 通常只起到了路由的作用(Backbonejs 干脆取消了 Controller 只留下了路由 Router),View 和 Controller 之间是有交流的,这就意味着他们之间是存在耦合的,这对大型开发是非常不友好的,会花费很多额外的开发、测试、维护的精力。
另外,在这种模式里,大部分的逻辑都会写在 View 层,这就让他有着 Controller 层非常薄而 View 层非常厚的特点。
有特点和缺点就会有改变,为了适应不同的开发背景,MVP 模式就出现了。
MVP(Model-View-Presenter)
在一些情况下用 MVC 模式,当你有变化的时候你需要同时维护三个对象和三个交互,这显然让事情复杂化了。MVP 模式就是将 MVC 中的 Controller替换成 Present,模型变成下面这样:
变化很明显,View 和 Model 完全没有交流,解耦了,都通过Presenter进行交流。
用户在 View 触发事件,交给 Presenter 处理。处理结果交给 Model 更新了 Model 的数据,Model 做完自己工作之后将更新好的结果交给 Presenter 处理,最后 Presenter 反馈给 View 更新相关。
Presenter 将 Model 的变化返回给 View,和 MVC 不同,Presenter会饭作用于 View ,不像 Controller 只会被动的接受 View 的指挥。正常情况下,发现可以抽象 View,暴露属性和事件,然后 Presenter 引用 View 的抽象,提高可单元测试性。在这里,Presenter 的责任变大了,不仅要操作数据,而且要更新 View。
View 只包含少量逻辑或者不部署任何业务逻辑,被称为被动动态,即没有任何主动性。在 MVP 下 View 就会非常薄,Presenter 会非常厚,通常所有的逻辑部署在 Presenter,这张特点会让测试和维护变得方便。
MVP 过了一段时间,MVVM 就出现了。
MVVM(Model-View-ViewModel)
先看一波模型
可以看出 MVVM 跟 MVP 其实差不多,不同的是改名为 ViewModel 的 Presenter 跟 View 层双向绑定了,这个 ViewModel 除了正常的属性意外,还包括一些供 View 显示用的属性,这意味着当你更新 ViewModel 层的数据的时候,View 层会相应的变动 UI。
在 MVVM 中,以前开发模式中必须先处理业务数据,然后根据的数据变化,去获取 UI 的引用然后更新 UI ,也是通过 UI 来获取用户输入,而在 MVVM中,数据和业务逻辑处于一个独立的 ViewModel 中,ViewModel 只要关注数据和业务逻辑,不需要和 UI 或者控件打交道。由数据自动去驱动 UI 并自动更新 UI ,UI 的改变又同时自动反馈到数据,数据成为主导因素,这样使得在业务逻辑处理只要关心数据,方便而且简单很多。
就是说在 MVVM 中,View 和 ViewModel 之间是松散耦合。一个是处理业务和数据,一个是专门的 UI 处理。完全可以两个人分工来做,一个做 UI 一个写 ViewModel,效率更高。
MVVM 架构非常突出的特点就是有数据的双向绑定,如最近流行 Angularjs,React,Vue 等等。
总结
最后我们还是要面对选择恐惧症:到底开发要选择哪一种架构?
通过上面的大家应该都了解了三者的关系区别和特点,但是我想说,虽然 MVP 和 MVVM 可以说是 MVC 发展或者改进的结果,但是我们不可以把一个架构看成是万能的,他们各自都是有自己缺点的。
MVP 的问题在于,由于我们使用了接口的方式去链接 View 层和 Presenter 层,这样就导致了一个问题,如果你有一个逻辑很复杂的页面,你的接口会有很多,十几二十个都不足为奇。想象一个移动应用中有很多个这样复杂的页面,维护接口的成本就会非常的大。
MVVM 的问题呢,其实和 MVC 有一点像。Data Binding 框架解决了数据绑定的问题,但是 View 层还是会过重。
下面是几个观点:
MVC 架构适合大型系统,它可以分层并且可以在实体层面分割成不同的模块。
MVP 适合集中由代码决定 View 变化的开发,而 View 只需要实作特定的界面即可,不需要太复杂的工作,但 Presenter 则可能会受限于 View 界面的动作,而无法做更进一步对 View 的控制。
MVVM 架构适合数据与逻辑操作松散耦合的情况。只要 View 中下特定的指令与 ViewModel 串接,就可以享有 ViewModel 沟通的功能,而 ViewModel 只需做一些特别的界面实作,即可平顺的和 View 沟通。
要用什么样的架构去设计,看当时的系统环境与需求来决定,而不是只想着要用同一种架构去做所有的系统,每种都有自身存在的价值,有自己的长处和短处,有自己发挥威力的地方,还是那句:
我们不可以把一个架构看成是万能的,所有离开实际谈选型的话题都是在耍流氓。
,