MVC、MVP、MVVM区别
网络上有很多类似的讨论。比如
廖雪峰:MVVM
司徒正美: 各自用一句话来概括MVC、MVP、MVVM的差异特点
。。。
但是说的往往比较概念化、空泛,初学者很难理解。本篇用最简单的例子讲解这三者,看完本篇,你就不会再纠结这个问题了
本文例子主要从MV*框架出发,实际上这些模式可以用到颗粒更小的层面。
框架的起源与目的
1.框架是一个可复用的设计构件
框架就是为大规模复用而生,为大型项目而生。小型项目由于不需要大规模复用,可不需要框架。
表现为组件的复用、项目的移植都应该非常容易。
2.框架规定了一种固定的、结构化的方式进行代码的组织。
框架的目标是进行有效的知识积累。为此,相关的技术当以固定的格式,以代码、文档、模型等方式固化下来。
表现为:框架规定了代码的结构层次(“高内聚、低耦合”),以及各个层次之间的关系;交互以及控制流程。
这块可能有点抽象,简单理解:框架就是规定了结构分层,每一层是干什么用的。然后你按照框架规定的范式进行编程,框架帮你处理层与层之间的交互与控制。
MVC
Model-View-Controller
view层:用户界面
controller层:业务逻辑、路由
model层:数据结构、数据存储
以jsp作为页面模板开发为例,其他asp/php等类似(为了方便,下面用V表示View,C表示controller, M表示Model。后面的例子同理)
view层:
jsp页面模板是属于这一层。
controller层:
响应jsp页面的用户操作并处理的Servlet。servlet控制改变Model层的数据。所以数据流程是C到M。
Servlet处理中路由功能会告诉服务器处理完成之后下一个展示的该是哪个jsp页面。这块仅仅是路由功能,servlet和“下一个展示的jsp页面”没有交互和数据的传递。所以V到C是单项的。
model层:
这一层主要定义基本数据结构和数据存储。jsp页面模板中,需要从M层获取最新的数据组装页面,所以是M到V。
到此,对MVC框架就应该比较了解了。
MVC模式有多种变种,数据流的方向可能也不同。但是有两个特点:三层隔离的数据模型、V和M层有数据交互。
MVP
Model-View-Presenter
view层:用户界面
presenter层:业务逻辑、路由
model层:数据结构、数据存储
为什么要MVP?从MVC的流程可以看到,V层数据是从M层获取的。最上层和最底层直接交互,意味着什么?
在前后端没有分工的时候没有问题,V层开发者就是M层开发者,所以对M的数据结构了如指掌,要什么数据知道怎么去获取。
但是V层越来越复杂、ajax做局部页面渲染的出现以及前后端分工导致V层开发者更专注于交互设计,已经没有精力去掌控M层的细节了。
这时,V层希望的是:有特定的接口返回约定好的数据。这些数据和M层的数据可能有很大的不同,应该有一个中间层来提供。之前的MVC的C层来干这件事比较合适。所以变成了P层,P层除了干C层的事,还多了为V层提供各种各样功能接口。
现在V层和M层完全分来了。前后端的开发人员都能将精力集中在该干的事上。
MVVM
Model-View-ViewModel
view层:用户界面、响应viewModel变化处理
viewModel层:界面业务逻辑、路由
model层:后台业务逻辑、数据结构、数据存储
前端的复杂度指数级的上升。比如你可以看到类似Scratch这样纯前端的图形化编程系统,代码量以千万行为单位,是有必要为这样庞大的系统做框架设计的。MVVM就是为此而生。
在MVVM的视界里,M层不是关键,你可以把整个后台都看成M层。
V层是用户界面,并且感知到VM层数据的变化V层会跟随变化(你不需要知道V层怎么感知到VM层数据变化的,这就是框架帮你做的事),可以称之为主动视图(这就是MVVM和MVP的区别,MVC/MVP的视图都是被动视图)。
VM层才是重点。在框架中,VM层定义了V层需要的直接数据结构(所以才带Model字样),V层的事件以及数据变化都会经过框架,流入VM层进行处理,进行业务逻辑的处理、数据的变更以及和M层的交互。
Angular、Vue、React都是类似的。简单理解:前端开发中模板即V层,后台属于M层,按照框架的范式开发的部分就是VM层。
细心的你可能看到了一点:VM层居然包含了“路由”功能。在MVC、MVP框架中,路由都是属于服务器功能,单页面的兴起,让路由纳入了前端的功能圈,MVVM框架非常适合单页面
当然这些MVVM框架都支持在服务端渲染,一旦用在服务端渲染,框架就失去了V层的响应式,直接就编程练一个模板引擎了,不能再称之位MVVM框架了。
到此,你应该对三种模式有了足够的认识了。
这三种模式从小的层面来说,可以构建一些简单的数据交互结构,大的层面可以用来构建框架。
从框架的层面和历史发展来看:MVC和MVP都主要为简化服务端渲染视图而设计的,MVVM则是为了简化前端页面开发而设计的。
从模式的方面来看:MVC、MVP和MVVM的思想可以用在更小的代码颗粒中。
上面的示例以Web页面来描述的。同理推广到其他视图交互应用都是可以的。
说一个题外话,框架和库的区别就比较明显了。库只是提供拓展的功能,而框架则是规定了代码分层,并让你必须按它的结构进行代码编写。这就是Jquery不是框架的原因。