MVC,MVP和MVVM之间的区别


后端已经进入了后REST时代,RESTful将MVC和MVP和MVVM从后端服务器端压缩到了前端,从而实现了前后端分离,前端目前以React.js Vue.js为主,ReactJS是通过事件源这种函数式实现模型和视图的绑定更新(ReduxFlux介绍),因此可以说,MVC, MVP和MVVM实则是过去落后的技术名词。但是初学者可能需要了解这些之间区别,特别找到一篇文章翻译如下:

MVC,MVP和MVVM是指导程序员创建解耦解决方案的一些常见模式。MVC,MVP和MVVM共有的软件行为是:

  • 数据层/业务逻辑(模型):这是将业务逻辑应用于应用程序数据的行为。域模型通常表示模型,其中对象用于模拟现实世界实体。
  • 表示层/ UI(视图):View负责应用程序的可视化表示。此行为向用户显示模型信息。
  • 应用程序逻辑(控制器,表示或视图模型):此行为包含实现模型和视图之间交互的逻辑。

MVC模式

  • MVC由三层Model,View和Controller组成。
  • MVC是一种复合模式
  • 它使用前端控制器模式,通过单个控制器处理Web应用程序请求。因此控制器是MVC中动作入口点。
  • 它不使用视图状态或基于服务器的表单。这使得MVC框架非常适合希望完全控制应用程序行为的开发人员。
  • 它为测试驱动开发(TDD)提供了更好的支持。
  • 它适用于大型开发人员团队支持的Web应用程序以及需要对应用程序行为进行高度控制的Web设计人员
  • 客户端库:Backbone.js,knockback.js,Spine.js,angular.js。
  • 服务器端库:ASP。NET MVC, Spring MVC, Ruby-on-Rails

(banq注:MVC模式中控制器是整个流程核心,用户看到的视图,但是想看到哪个视图,需要通过控制器选择,哪个视图对应哪个模型也是在控制器内部完成。)

MVP模式

  • MVP由三层Model,View和Presenter组成。
  • 在MVP中,视图和模型更松散地耦合,提供更清晰的关注点分离。
  • MVP,View负责将用户输入委派给Presenter。
  • MVP,Presenter和View应该具有1-1关系,每个View都通过界面引用其Presenter。
  • MVP,view直接通过数据绑定绑定到Model。
  • 在MVP中,单元测试更容易,因为View通过易于模拟的界面了解Presenter。
  • 客户端库:Riot.js,GWT
  • 服务器端库:经典ASP. NET,JSP Servlets。

(banq注:MVP与MVC的区别是用Presenter替代了控制器Controller,这个模式在.NET中比较普及,JSP Servlet其实是用于MVC实现,Struts等背后都是基于JSP/Servlet的MVC框架,MVP中视图能动性更强些,不像MVC中M和V都是被动的,靠控制器推动。)

MVVM​​​​​​​

  • MVVM模式是处理WPF和Silverlight应用程序此类问题的最佳解决方案之一。
  • 当您为WPF使用MVVM模式时,Silverlight视图将不具有在UI代码中如此常见的典型事件处理程序。
  • MVVM在UI和应用程序逻辑之间提供了清晰的分离。
  • 客户端库:Knockout.js,Kendo(MVVM)
  • 服务器端库:WPF(桌面)或Silverlight,Windows Phone应用程序(XAML),Adobe Flex
  • MVVM模式包括三个关键部分:

  1.  模型(业务规则,数据访问,模型类)
  2. 查看(用户界面(XAML))
  3. ViewModel(视图和模型之间的代理或中间人)

(banq注:MVVM使用ViewModel视图模型替代控制器和Presenter,ViewModel简称VM,别以为又多了一个组件,还是三个组件,主要是.NET中用得比较多,这种模式类似前端双向或单向绑定,如果说,MVP中Presenter还要兼顾视图和模型,那么在MVVM中ViewModel直接和Model对应绑定;MVC和MVP中动作和数据都是分离的,数据在视图和模型中,控制器或Presenter通过动作调用将两者对应混合起来;但是在MVVM中,动作通过绑定融合了数据之中,通过事件或观察者模式实现调用了。ReatJS等前端框架在这个基础上发展其Flux等Reactive响应式框架。)

对该模式的批评来自MVVM创建者John Gossman本人,他指出实现MVVM的开销对于简单的UI操作来说是“过度杀伤”;对于更大的应用程序,概括提炼一个ViewModel变得很困难。此外,他说明在非常大的应用程序中的数据绑定可能导致相当大的内存消耗。