前端面试系列【010】 – 谈一谈你对 MVC、MVP 和 MVVM 的理解

时间:2020-9-13 作者:admin

对于这个问题,我想大部分“新生代”的前端程序员很难有切身的体会。毕竟这是一个比较漫长的历史演变问题,很多人一开始从事前端开发的时候,就已经是 vue, react, angular 的时代了。

这里大致介绍一下前端工程从无到有,从有到优的变迁过程吧!相信看完这个演变过程之后,对于上面提出的问题就有一定的认知了。

Web 1.0 时代

这是最早期的网络时代,故且称作 Web 1.0 时代吧!(当然你也可以将其称为上古时代)

这个时候还没有前端的概念,开发一个 web 应用主要采用 ASP.NET、Java、PHP 来进行编写,而项目通常由多个 aspx、jsp、php 文件构成,每个文件中都包含了 HTML,CSS,JS,C#、Java、PHP 代码,系统的整体结构及其混乱。(这个时候的 web 漏洞也是相当多,什么 Java 反序列化漏洞,SQL 注入,越权访问,一句话木马上传等等)

前端面试系列【010】 - 谈一谈你对 MVC、MVP 和 MVVM 的理解

这样开发的好处是方便快捷,但同时缺点也非常明显:JSP 部分的代码非常难以维护。(可以想象以下,一个文件里既有 HTML,CSS,JS 又有后端代码,是多么恐怖的场景。)

所以,为了让代码更易于维护,区分前后端职责,便衍生出了 MVC 架构模式(这里所谓的 MVC 是指后端的 MVC),其典型框架为 Spring,Structs(前面提到的反序列化漏洞就是它),Hibernate。

在有了 MVC 架构之后,应用的整体架构如下图所示:

前端面试系列【010】 - 谈一谈你对 MVC、MVP 和 MVVM 的理解

使用这种分层的架构,代码易于维护了。但这个架构 MVC 仅限于后端部分,前端部分整体上只做为后端开发中的 view 层,这也就导致一些问题:

  • 前端页面开发效率不高
  • 前后端职责依然不清晰(因为前端页面直接通过 JSP 返回给浏览器,通常那个时候的工程师要么后端工程师一手抓,要么前端仅仅开发静态页面,按照木板语法填写变量,整体依然混乱)

这就是整个 Web 1.0 时代的前端变迁了。

Web 2.0 时代

Web 2.0 时代的标志是 Gmail 的出现,ajax 技术风靡全球。

ajax 带来的改变是非常显著的,因为前端可以通过 ajax 技术与后端进行数据交互了,这就说明前端可以分担后端的数据压力了,这个时候,整体应用的架构变成了下面这样:

前端面试系列【010】 - 谈一谈你对 MVC、MVP 和 MVVM 的理解

通过 ajax 与后端进行数据互通,让前后端职责更加清晰,后端关注数据,而前端关注页面,并且由于 ajax 可以使得页面内容实现部分刷新,而不是整个页面重新渲染,也让用户体验更加友好。一直到这个时候,才真正意义上有了专职的前端工程师。同一时间,前端的类库也开始慢慢发展,其中最为出名的就是 jQuery 了。

同样的,这样的架构也存在自己的问题:那就是前端代码都杂糅在一起,缺乏模块化的开发模式,一旦应用规模增大,业务场景变得复杂,前端部分的代码就变得难以维护。

因此,借鉴了后端的 MVC 结构,前端的 MVC 架构模式也随之诞生了。

Web 3.0 时代

这个时候的标志是前后端分离后,前端 MVC 到 MVP 以及 MVVM 的演变。

MVC

与后端的 MVC 架构类似,这个架构具备以下三个模块:

  • View:视图端,负责视图展示,展示 Model 中的数据
  • Controller:控制端,负责业务逻辑,根据用户行为对 Model 数据进行修改
  • Model:负责存储数据,与后端的数据进行同步

其架构如下所示:

前端面试系列【010】 - 谈一谈你对 MVC、MVP 和 MVVM 的理解

在这样的模型中,对前端实现了模块化,功能化区分,但其缺点也是明显的:对于繁杂的前端业务来说,每一个微小的事件都需要经过完整的这样一个流程,对于开发来说非常不便捷,不但没有提升开发效率,反而降低了开发效率。

虽说为了后期的维护,一定的开发成本是可以接受的,但显然单纯的 MVC 模式的开发成本太高了。

于是就出现了下面的变种:

前端面试系列【010】 - 谈一谈你对 MVC、MVP 和 MVVM 的理解

显然,这个模型相较于上面来说要灵活许多,但这样的灵活代价也是不菲的,其中最主要的就是数据流混乱(因为视图也可以更改数据,控制器也可以更改数据,没有保证单项数据流)

前端面试系列【010】 - 谈一谈你对 MVC、MVP 和 MVVM 的理解

并且由于 View 也可以操作数据,导致许多的开发者直接在 View 中编写大量的业务逻辑代码,导致 Controller 变得越来越淡薄,失去意义。

MVP

事实上,在前端开发中,这个模式并不常见(因为 Angular 早早的就将 MVVM 框架模式带入了前端),但这个模式并非没有任何价值,在原生 Android 的开发中,开发者还是会经常使用到它。

与 MVC 相比,MVP 唯一的区别就在于这个 P(Presenter),这个 Presenter,可以理解为一个中间人,它完全负责 View 和 Model 之间的数据流动,防止 View 和 Model 之间的直接交流:

前端面试系列【010】 - 谈一谈你对 MVC、MVP 和 MVVM 的理解

事实上,从这个图就能看出,当应用逐渐增大的时候,Presenter 一定会逐渐变得臃肿,难以维护。

有缺陷,就有变革,MVVM 就很好的继承了 MVP 分离 View 和 Model 的优点,又解决了中间层过与庞大臃肿的问题。

MVVM

我们都知道,MVVM 可以拆分为 M,V 和 VM(ViewModel),如下图所示:

前端面试系列【010】 - 谈一谈你对 MVC、MVP 和 MVVM 的理解

看起来,仿佛和 MVP 没什么区别,那么它是如何解决中间层过于臃肿的问题的呢?

其核心就是数据响应式系统,开发者在开发应用的时候,只需要通过模板将数据和视图绑定起来之后,后续通过事件监听修改数据,视图会自动更新,而底层的操作对于开发者来说实际上是不关心的。这样的设计使得开发成本和维护成本都显著降低,让开发者可以专注业务逻辑的开发,而不用关心当数据改变,应该如何更新视图。

总结

通过整个流程的梳理,我们可以总结出一些要点:

  • MVC、MVP 和 MVVM 三者都是框架模式,其设计目标都是为了解决 View 和 Model 的耦合问题
  • MVC 早期主要出现在后端,如 Spring MVC。前端也有应用到 MVC 的框架,如Backbone.js,同时它的优缺点都很明显:优点是分层清晰,缺点是数据流混乱,维护性较差
  • MVP 是 MVC 的一种还中,P 层作为中间层负责 M 和 V 之间的通信,但随着应用规模的增加,P 层也会由于过于臃肿而导致难以维护
  • MVVM 可以当作是 MVP 的进化,它在前端领域中有着广泛的应用,它不但解决了 MV 耦合的问题,还同时解决了作为中间层当应用规模增加的时候需要维护二者映射关系而产生的大量繁杂代码的问题,提高了开发效率,可读性和维护性。同时,随着对 MV 层的优化(虚拟 DOM,diff 算法,模板编译),还保持了优越的性能。

结语

更佳阅读体验:010 – 谈一谈你对 MVC、MVP 和 MVVM 的理解

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。