前言:这三个表现层框架设计模式是依次进化而形成MVC—>MVP—>MVVM。在以前传统的开发模式当中即MVC模式,前端人员只负责Model(数据库)、 View(视图)和 Controller /Presenter/ViewModel(控制器) 当中的View(视图)部分,写好页面交由后端创建渲染模板并提供数据,随着MVVM模式的出现前端已经可以自己写业务逻辑以及渲染模板,后端只负责提供数据即可,前端所能做的事情越来越多。众所周知当下是 MVVM 盛行的时代,从早期的 Angular 到现在的 React 和 Vue ,再从最初的三分天下到现在的两虎相争,无疑不给我们的开发带来了一种前所未有的新体验,告别了操作 DOM 的思维,换上了数据驱动页面的思想,果然时代的进步,改变了我们许多许多。
1、MVC模 式
MVC是一种目前广泛流行的软件开发设计模式,它实现了显示模块与业务处理的分离。提高了程序的可维护性、可移植性、可扩展性与可重用性,降低了程序的开发难度。近年来,随着 Java EE的 成 熟 ,MVC 成为了 Java EE平台上推荐的一种设计模式。MVC 强制性地把一个应用的输入、处理、输出流程按照 视图、控制、模型的方式进行分离,形成了控制器、模型、视图三个核心模块。
( 1 ) 控 制 器 (Controller): 接受用户的输入并调用模型和视图去完成用户的需求。该部分是 用户界面与Model 的接口。 一方面它解释来自于视图的输入,将其解释成为系统能够理解的对 象,同时它也识别用户动作,并将其解释为对模型特定方法的调用;另一方面,它处理来自于 模型的事件和模型逻辑执行的结果,调用适当的视图为用户提供反馈。
( 2 ) 模 型 (Model): 应用程序的主体部分。模型表示业务数据和业务逻辑。 一个模型能为多个视图提供数据。由于同一个模型可以被多个视图重用,所以提高了应用的可重用性。
( 3 ) 视 图 (View): 用户看到并与之交互的界面。视图向用户显示相关的数据,并能接收用 户输入的数据,但是它并不进行任何实际的业务处理。视图可以向模型查询业务状态,但不能 改变模型。视图还能接受模型发出的数据更新事件,从而对用户界面进行同步更新。
三者的协作关系如图所示。
从图中可以看到,首先,控制器接收用户的请求,并决定应该调用哪个模型来处理; 然后,模型根据用户请求进行相应的业务逻辑处理,并返回数据;最后,控制器调用相应的视 图来格式化模型返回的数据,并通过视图呈现给用户。
使用 MVC 模式来设计表现层,可以有以下的优点。
(1)有利于组件的重用,允许多种用户界面的扩展::在MVC 模式中,视图与模型没有必然的联系,都是通过控制器发生关系,这样如果要增加新类型的用户界面,只需要改动相应的视图和控制器即可, 而模型则无须发生改动。简单来说,如控制层可独立成一个能用的组件,表示层也可做成通用的操作界面,这样可以为一个模型在运行时同时建立和使用多个视图。
(2)降低代码耦合性,易于维护:在 MVC 模式中,三个层各施其职,所以如果一旦哪一层的需求发
生了变化,就只需要更改相应的层中的代码而不会影响到其他层中的代码。控制器和视图可以随着模型的扩展而进行相应的扩展,只要保持一种公共 的接口,控制器和视图的旧版本也可以继续使用。
(3)有利于分工合作:在 MVC 模式中,由于按层把系统分开,那么就能更好的实现开发中的分工。网页设计人员可进行开发视图层中的 JSP,而后端的开发人员可开发业务控制层。
MVC 是构建应用框架的一个较好的设计模式,可以将业务处理与显示分离,将应用分为控制器、模型和视图,增加了应用的可拓展性、强壮性及灵活性。基于MVC 的优点,目前比较先进的 Web 应用框架都是基于MVC 设计模式的。
2、MVP模式
全称:Model-View-Presenter ;MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。
当然 MVP 与 MVC 也有一些显著的区别, MVC 模式中元素之间“混乱”的交互主要体现在允许View 和 Model 直接进行交流,这在MVP 模式中是不允许的。在MVP 中 View 并不直接使用Model, 它们之间的通信是通过Presenter(MVC中的Controller) 来进行的,所有的交互都发生在 Presenter 内部,而在 MVC 中 View 会直接从Model 中读取数据而不是通过Controller。
MVP 不仅仅避免了View 和 Model 之间的耦合,还进一步降低了Presenter 对 View 的依赖。 Presenter 依赖的是一个抽象化的View, 即 View 实现的接口IView, 这带来的最直接的好处,就是使定义在 Presenter 中 的 UI 处理逻辑变得易于测试。由于 Presenter 对 View 的依赖行为定义在接 口IView 中,只需要一个实现了这个接口的View 就能对 Presenter 进行测试。MVP 的结构如图所示。
使用 MVP 模式来设计表现层,可以有以下的优点。
(1)模型与视图完全分离,可以修改视图而不影响模型。
(2)可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter 内部。
(3)可以将 一 个Presenter 用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
(4)如果把逻辑放在 Presenter 中,就可以脱离用户接口来测试这些逻辑(单元测试)。
目 前 ,MVP 模式被更多地用在 Android 开发当中。
3、MVVM 模式
MVVM是Model-View-ViewModel的简写。MVVM 可以算是 MVP 的升级版。 其中的 VM 是 ViewModel 的缩写,ViewModel 可以理解成是 View 的数据模型和 Presenter 的合体。ViewModel 和 View 之间的交互通过 Data Binding 完成,而 Data Binding 可以实现双向的交互,这就使得视图和控制层之间的耦合程度进一步降低,关注点分离更为彻底,同时减轻了 Activity 的压力。MVVM 模式正是为解决 MVP 中 UI 种类变多,接口也会不断增加的问题而提出的。
MVVM 和 MVC 、MVP 类似,主要目的都是为了实现视图和模型的分离,不同的是MVVM 中 ,View 与 Model 的交互通 过ViewModel 来 实 现 。ViewModel 是 MVVM 的 核 心 , 它 通 过 DataBinding 实 现 View 与 Model 之间的双向绑定,其内容包括数据状态处理、数据绑定及数据转换。例如, View 中某处 的状态和Model 中某部分数据绑定在一起,这部分数据一旦变更将会反映到View 层。而这个机制通过 ViewModel 来实现。
ViewModel, 即视图模型,是一个专门用于数据转换的控制器,它可以把对象信息转换为视图信息,将命令从视图携带到对象。它通过View 发布对象的公共数据,同时向视图提数据和方 法 。View 和 ViewModel 之 间 使 用 DataBinding 及其事件进行通信。View 的用户接口事件仍然由View 自身处理,并把相关事件映射到ViewModel, 以实 现View 中的对象 与视图模型内容的同步,且可通过双向数据绑定进行更新。因此,程序员只需编写包含声明绑定的视图模板,以及ViewModel 中的数据变更逻辑,就能使View 获得响应式的更新。 MVVM 流程设计如图所示。
在 MVVM 模式下View 和 Model 不能直接通信,两者的通信只能通过ViewModel 来实现。 ViewModel 通常要实现一个观察者,当数据发生变化, ViewModel 能够监听到数据的变化,然 后通知对应的视图做自动更新;而当用户操作视图, ViewModel 也能监听到视图的变化,再通知数据做改动,从而形成数据的双向绑定。这使得MVVM 更适用于数据驱动的场景,尤其是 数据操作特别频繁的场景。
但也正是由于数据和视图的双向绑定,导致出现问题时不太好定位来源,有可能由数据问题导致、也有可能由业务逻辑中对视图属性的修改导致。若项目中有计划采用MVVM, 倾向建议使用官方的架构组件ViewModel 、LiveData 等去实现 MVVM。
目 前 ,MVVM模式被更多地用在 前端Vue开发当中。
4、MVC、MVP、MVVM模式的区别
(1)MVP与MVC区别:
作为一种新的模式,MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过 Controller。
在MVC里,View是可以直接访问Model的!从而,View里会包含Model信息,不可避免的还要包括一些业务逻辑。 在MVC模型里,更关注的Model的改变,而同时有多个对Model的不同显示,即View。所以,在MVC模型里,Model不依赖于View,但是View是依赖于Model的。不仅如此,因为有一些业务逻辑在View里实现了,导致要更改View也是比较困难的,至少那些业务逻辑是无法重用的。
虽然 MVC 中的 View 的确“可以”访问 Model,但是我们不建议在 View 中依赖 Model,而是要求尽可能把所有业务逻辑都放在 Controller 中处理,而 View 只和 Controller 交互。
(2)MVVM与MVP区别:
mvvm模式将Presener改名为View Model,基本上与MVP模式完全一致,唯一的区别是,它采用双向绑定(data-binding): View的 变动,自动反映在View Model,反之亦然。这样开发者就不用处理接收事件和View更新的工作,框架已经帮你做好了。
(3)什么是双向绑定?
单向绑定:
单项绑定就是把model绑定到view上,通过js更新model数据时,view视图跟着更新双向绑定:
如果用户更新了view视图,model数据也会跟着更新,这就是双向绑定。
什么情况下用户可以更新View呢?填写表单就是一个最直接的例子。当用户填写表单时,View的状态就被更新了,如果此时MVVM框架可以自动更新Model的状态,那就相当于我们把Model和View做了双向绑定:
举例:当用户填写表单时,view视图就更新了,input输入的值自动更新model中对应的数据,这就相当于我们把view和model做了双向绑定
在浏览器中,当用户修改了表单的内容时,我们绑定的Model会自动更新:
在Vue中,使用双向绑定非常容易,我们仍然先创建一个VM实例:
$(function () {var vm = new Vue({el: '#vm',data: {email: '',name: ''}});window.vm = vm;
});
然后,编写一个HTML FORM表单,并用v-model
指令把某个<input>
和Model的某个属性作双向绑定:
<form id="vm" action="#"><p><input v-model="email"></p><p><input v-model="name"></p>
</form>
我们可以在表单中输入内容,然后在浏览器console中用window.vm.$data
查看Model的内容,也可以用window.vm.name
查看Model的name
属性,它的值和FORM表单对应的<input>
是一致的。
如果在浏览器console中用JavaScript更新Model,例如,执行window.vm.name='Bob'
,表单对应的<input>
内容就会立刻更新。
参考链接:
架构师必修系列:MVC、MVP、MVVM 三者的区别介绍
MVC、MVP、MVVM模式的概念与区别 - 简书
廖雪峰-双向绑定