浅谈MVC/MVP/MVVM模式(概述)

本文来自个人博客 这个想法不必定对系列,so,这个想法不必定对😉

一切皆为数据(0,1),一切皆可量化jquery

无论承不认可,页面的展现都是数据的可视化。HTML 是数据,CSS 是数据,JS也是数据。只是这些数据的组合最终变成了咱们想要的效果。浏览器

最为直观的是,咱们在开发者工具 Console 控制台中,输入任何形式的数据并点击 Enter 时,最终会在下方显示出来(前提是输入正确的数据类型和格式)。又或者,咱们用某些参数从服务请求一个 JSON 文件,浏览器上就会展现文件内容。数据 => 视图,就是这么简单直接。框架

引子

然而,实际上的状况远远比这复杂。为了更好的视觉享受和用户体验,浏览器上的页面效果愈来愈炫,交互逻辑也愈来愈复杂。咱们拿到的第一手数据(或来自用户,或来自服务)已经不能直接用来展现了,而是要通过相应的逻辑处理(在这里咱们称第一手数据为源数据,通过逻辑处理后的数据称为目标数据)。视图上的数据就是目标数据的映射。mvvm

而处理后的数据又该如何展现呢?是基于 DOM 作操做,仍是基于目标数据从新渲染呢?二者均可,前者是以 jQuery 为表明,后者则是以 Vue 等新框架为主。举个例子🌰,对于某个 DOM 元素的显隐。ide

< !--jQuery -->
  <div id='jquery'></div>
$('#jquery').hide();

< !--Vue -->
  <div id='jquery' v-show={id[jquery]}></div>
data: {
  id: {
    jquery: fasle
  }
}

基于 DOM 操做, 若是咱们须要对这个 DOM 随时改变显隐,就须要不断操做 DOM 来更改样式。 若是基于数据操做,咱们只须要更改 jQuery 的值便可。工具

咱们再回到刚才的话题,对于复杂的交互页面,数据 => 视图 的关系已经再也不像以前那么纯净了。为了应付复杂的场景,数据视图 再也不是狭义上的数据和视图。数据包括了数据和数据相关的操做,视图包括了视图和对视图相关的一些操做。spa

MV*模式

借用MV* 框架模式,这里的 数据视图 对应着 ModelView. 简单点的页面,Model - View 彻底可以应付过来。可是复杂的场景,ModelView 会分担太多的逻辑而显得臃肿,甚至可能包含了不在本身职责范围内的逻辑。设计

此时咱们就要借助第三者来协调 ModelView 之间的关系。如何合做,其实也早有了相应的解决方案。好比 MVC、MVP、MVVM。由于重点始终在于协调 ModelView,因此它们统称为 MV*code

MVC&MVP.jpg

MVC (Model(模型)-View(视图)-Controller(控制器)), MVP (Model(模型)-View(视图)-Presenter(中介者)) 以及 MVVM (Model(模型)-View(视图)-ViewModel(视图模型)),是种模式也是种抽象的概念。开发

每一种模式在实践中可能存在着不一样的变体,但这不妨碍它们属于同一个模式。每一种模式的不一样变体都是为了解决不一样问题而产生的,因此它们没有什么优劣之分。

如今咱们就把三种模式拟人化来阐述不一样模式的运做方式。

由四节电池驱动的J-20模型:
J-20.jpg

MVC

公司:飞机模型制造商 => 生产的飞机模型能够自主塑形。

模式:MVC

飞机模型 V:由模型数据生产出的模型。职责有:由模型数据自主塑形、将收集用户反馈并转发。

工程师 M:负责将客服的需求参数转换成最终的模型数据。职责有:对数据的操做、通知飞机模型更新。

工程师 C:协调 M 和 V。负责响应用户、调用工程师M生成目标数据。

首先咱们要知道,客户提出了想要一个 60cm * 60cm 的飞机模型,这个需求到了制造商那里确定不是给出个 60cm * 60cm 的小方块,而是根据需求计算处理生产真正的飞机模型(好比什么样的造型设计才能最大减小阻力),工程师M的工做之一就是根据原始数据并结合特定的逻辑规则给出最终的模型数据。

如今,用户手里有一飞机模型V,不过这个飞机模型的飞机双翼和用户想象的不同。因而用户根据飞机模型上提供的方式反馈了问题(好比飞机模型提供了留言功能,用来收集用户反馈)。工程师C收到了反馈后,把工程师M拉过来对数据进行处理并生成新的模型数据,并让工程师M通知到共享相同数据的飞机模型去更新数据自主调整。

插一句,说到调整,咱们有两种方式。一个是,咱们能够针对用户不满意的地方(飞机双翼)进行调整。一个是,咱们飞机模型格式化按照最新的数据模型从新初始化一下。前者能够认为就是基于 DOM 操做的方式,后者就是基于数据的处理方式。

在 MVC 中,Model 和 View 之间耦合,视图的更新须要 Model 去直接通知。Model 内由于有 View 的引用才能让视图更新。

MVC.png

MVP

若是 Model 只想作数据相关的操做,把通知 View 的逻辑挪到了 Control 里,这时 Control 摇身一变称为了 Presenter。由于解耦了 Model 和 View,也使得它们的职责划分更加清晰。

公司:飞机模型制造商 => 生产的飞机模型能够自主塑形。

模式:MVP

飞机模型 V:由模型数据生产出的模型。职责有:由模型数据自主塑形、将收集用户反馈并转发。

工程师 M:负责将客服的需求参数转换成最终的模型数据。职责有:对数据的操做。

工程师 P:协调 M 和 V。负责响应用户、调用工程师M生成目标数据、更新视图。

在 MVP 模式中,工程师M的工做专一于数据,通知的活甩给了工程师P。
和 MVC 一样的场景,工程师P接到反馈后,把工程师M拉过来处理了数据,而后又让飞机模型依据已经处理后的数据自主调整。每次数据的变化都要主动去通知视图更新。

MVP.png

MVVM

若是数据变化可以自主触发视图更新,对 Presenter 来讲也会轻松很多。因而 Presenter 再次摇身一变 称为了 ViewModel。

公司:飞机模型制造商 => 生产的飞机模型能够自主塑形。

模式:MVVM

飞机模型 V:由模型数据生产出的模型。职责有:由模型数据自主塑形、将收集用户反馈并转发。

工程师 M:负责将客服的需求参数转换成最终的模型数据。职责有:对数据的操做。

工程师 VM:协调 M 和 V。负责响应用户、调用工程师M生成目标数据并更新视图。

MVVM.png

在 MVVM 中,View 和 Model 的变化彷佛不大。为了在数据变化后可以自动更新视图,ViewModel 进行了所谓的数据绑定。ViewModel 将 目标数据 和视图进行了绑定,在最终生成目标数据时,会触发视图的更新。

在这里咱们能够想象有两份数据,一份是源数据,一份是目标数据。绑定视图的是目标数据,这样,咱们直接修改目标数据时会触发视图更新。若是是源数据经处理后赋给目标数据,目标数据也会改变,也会触发试图更新。

总之,在 MVVM 中,视图是目标数据的可视化,经过改变视图里的数据也就等于改变了目标数据。

和 MVC、MVP 一样的场景,不过科技发达了,工程师VM有个自动化处理程序。用户反馈了问题,工程师VM的这个自动处理程序接到反馈自动处理并将结果发给飞机模型让其自主调整。

如下是Vue的MVVM示意图:
mvvmVue.png
MVC、MVP和MVVM大体就是如此,根据三种模式以及不一样场景,最终演变出了不一样的变体。

可是,不一样的变体是针对不一样问题的解决方案,指不定后来还会有 MVA、MVB..., 谁知道呢

相关文章
相关标签/搜索