MVC和MVVM有什么区别?

标准的“模型视图控制器”模式和微软的模型/视图/视图模式模式有区别吗?

MVC / MVVM不是一个/或select。

这两种模式在ASP.Net和Silverlight / WPF开发中都以不同的方式出现。

对于ASP.Net,MVVM用于在视图内双向绑定数据。 这通常是客户端的实现(例如使用Knockout.js)。 另一方面,MVC是一种在服务器端分离问题的方法。

对于Silverlight和WPF,MVVM模式更具包容性, 似乎可以替代MVC(或将软件组织成单独职责的其他模式)。 经常出现这种模式的一个假设是, ViewModel简单地取代了MVC的控制器(就像你可以用VMreplaceC中的首字母缩写词一样,所有的东西都可以被原谅)。

ViewModel并不一定取代单独的控制器的需要。

问题是:要独立testing*,特别是在需要时可重用,视图模型不知道视图显示的是什么,更重要的是不知道数据来自哪里

*注意:实际上,控制器从ViewModel中删除了大部分需要进行unit testing的逻辑。 虚拟机然后成为一个愚蠢的容器,需要很less,如果有的话,testing。 这是一件好事,因为虚拟机只是devise者和编码器之间的桥梁,所以应该保持简单。

即使在MVVM中,控制器通常也会包含所有的处理逻辑,并决定使用哪个视图模型在哪些视图中显示哪些数据。

从迄今为止我们所看到的ViewModel模式的主要优点,即从XAML代码中移除代码,使XAML编辑成为一项更加独立的任务 。 我们仍然在需要时创build控制器来控制(无双关语意思)我们应用程序的整体逻辑。

我们遵循的基本MVCVM指南是:

  • 视图显示一定形状的数据 。 他们不知道数据来自哪里。
  • ViewModel 拥有一定forms的数据和命令 ,他们不知道数据或代码来自何处或显示的方式。
  • 模型包含实际数据 (各种上下文,商店或其他方法)
  • 控制器监听和发布事件。 控制器提供控制什么数据被看见和在哪里的逻辑。 控制器将命令代码提供给ViewModel,以便ViewModel实际上是可重用的。

我们还注意到, Sculpture的代码生成框架实现了MVVM和一个类似于Prism的模式,并且还广泛使用控制器来分离所有的用例逻辑。

不要认为控制器被View-models过时了。

我已经开始了一个关于这个话题的博客,我会尽可能的补充 。 将MVCVM与常见的导航系统相结合存在问题,因为大多数导航系统只是使用视图和虚拟机,但我将在后面的文章中介绍。

使用MVCVM模型的另外一个好处是只有控制器对象需要在应用程序的整个生命周期内存在内存中,并且控制器主要包含代码和很less的状态数据(即微小的内存开销)。 这比需要保留视图模型的解决schemeless得多的内存密集型应用程序,对于某些types的移动开发(例如,使用Silverlight / Prism / MEF的Windows Mobile)是理想select。 这当然取决于应用程序的types,因为您可能仍然需要保留偶尔caching的虚拟机以实现响应。

注意:这篇文章已经被编辑了很多次,并没有专门针对狭义的问题,所以我已经更新了第一部分,现在也覆盖了。 下面的评论大部分的讨论只涉及ASP.Net而不是更广泛的图景。 本文旨在涵盖Silverlight,WPF和ASP.Net中MVVM的广泛使用,并尝试避免人们用ViewModelreplace控制器。

我认为理解这些缩略词应该是什么意思的最简单方法就是暂时忘记它们。 相反,想想他们的软件,每一个。 这真的归结为早期的networking和桌面之间的差异。

第一个首字母缩略词MVC起源于networking。 (是的,它可能已经在那里,但networking是如何普及到广大networking开发人员。)认为数据库,HTML页面和代码之间。 让我们来简单介绍一下MVC:对于数据库«,我们假设数据库加接口代码。 对于»HTML页面«,我们假设HTML模板加上模板处理代码。 对于»代码介于中间«,让我们假设代码映射用户点击行动,可能影响数据库,肯定会导致另一个视图显示。 就是这样,至less就这个比较而言。

让我们保留这个网页的一个特点,而不是像现在这样,但是正如十年前那样,当Javascript是一个低级的,卑鄙的烦恼时,真正的程序员很好地避开了:HTML页面本质上是愚蠢的,被动的。 浏览器是一个瘦客户端,或者如果你愿意,一个贫穷的客户端。 浏览器中没有智能。 整页重新加载规则。 “观点”每次都会重新产生。

让我们记住,尽pipe风靡一时,但这种networking方式与台式机相比却非常落后。 如果愿意,桌面应用程序是胖客户端或富客户端。 (甚至像Microsoft Word这样的程序也可以被认为是客户端,客户端是文档客户端。)他们是充满智慧的客户,对数据充满了知识。 他们是有状态的。 他们caching他们在内存中处理的数据。 没有像整页重新加载这样的废话。

而这种丰富的桌面方式可能是第二个缩写起源MVVM的地方。 不要被这些信件所迷惑,而忽略了C.控制者仍然存在。 他们需要。 没有东西被删除。 我们只是添加一件事:有状态,在客户端caching的数据(以及处理这些数据的智能)。 这个数据本质上是客户端的一个caching,现在被称为»ViewModel«。 这是允许丰富的交互性。 就是这样。

  • MVC =模型,控制器,视图=基本单向通信=交互性差
  • MVVM =模型,控制器,caching,视图=双向通信=丰富的交互性

我们可以看到,使用Flash,Silverlight和 – 最重要的是 – Javascript,Web已经接受了MVVM。 浏览器不能再被合法地称为瘦客户端。 看看他们的可编程性。 看看他们的内存消耗。 看看现代网页​​上的所有Javascript交互性。

就我个人而言,我觉得这个理论和首字母缩略词业务更容易理解,通过在具体实际中看它是指什么。 抽象的概念是有用的,特别是在具体问题上进行展示时,理解可能会完整。

MVVM Model-View ViewModel与MVC, Model-View Controller类似

控制器被replace为ViewModel 。 ViewModel位于UI层下面。 ViewModel公开视图需要的数据和命令对象。 你可以把它看作一个容器对象,这个容器对象可以从中获取数据和动作。 ViewModel从模型中提取数据。

罗素东做了一个博客更详细的讨论为什么MVVM是不同于MVC

首先,MVVM是使用XAML处理显示的MVC模式的进展。 本文概述了两者的一些方面。

Model / View / ViewModel体系结构的主要重点似乎是在数据之上(“模型”),另一层非可视化组件(“ViewModel”)更紧密地映射数据的概念到数据视图的概念(“视图”)。 它是View绑定的ViewModel,而不是直接的Model。

您可以在Windows环境中看到 MVVM模式的解释 :

在Model-View-ViewModeldevise模式中,应用程序由三个通用组件组成。 在这里输入图像说明

  • 模型 :这表示您的应用程序使用的数据模型。 例如,在图片共享应用程序中,该图层可能代表设备上可用的图片集以及用于读取和写入图片库的API。

  • 查看 :一个应用程序通常由多个UI页面组成。 向用户显示的每个页面都是MVVM术语中的一个视图。 该视图是用于定义和设置用户所看到的样式的XAML代码。 将模型中的数据显示给用户,ViewModel的工作是根据应用的当前状态向用户界面提供这些数据。 例如,在图片共享应用中,视图将是向用户显示设备上的相册列表,相册中的图片以及可能向用户显示特定图片的另一个用户界面。

  • ViewModel :ViewModel将数据模型或简单的模型绑定到应用程序的UI或视图。 它包含用于pipe理模型中数据的逻辑,并将数据公开为一组XAML UI或视图可以绑定的属性。 例如,在图片共享应用程序中,ViewModel会公开一张专辑列表,并为每个专辑公开一张图片列表。 用户界面不知道图片来自哪里以及如何检索。 它只是知道由ViewModel公开的一组图片并将其显示给用户。

我认为主要的区别之一是在MVC中,你的V直接读你的M,并通过C来操纵数据,而在MVVM中,你的VM充当M代理,并且为你提供可用的functionV.

如果我不是垃圾,我很惊讶没有人创build一个混合,您的虚拟机只是一个M代理,而C提供所有function。

MVVM是演示模型模式的改进(有争议)。 我说有争议,因为唯一的区别在于WPF如何提供数据绑定和命令处理能力。

视图模型是用户界面元素的“抽象”模型。 它必须允许您以不可视的方式执行命令和视图中的操作(例如对其进行testing)。

如果你曾经使用过MVC,你可能有时候发现创build模型对象来反映你的视图状态,例如,显示和隐藏一些编辑对话框,等等。在这种情况下,你正在使用视图模型。

MVVM模式仅仅是这个练习对所有UI元素的泛化。

而且这不是微软模式,WPF / Silverlight数据绑定特别适合使用这种模式。 但是,例如,没有什么能够阻止你将它用于Java服务器端。

简单的区别:(受Yaakov's Coursera AngularJS课程启发)

在这里输入图像说明

MVC (模型视图控制器)

  1. 模型:模型包含数据信息。 不要调用或使用Controller和View。 包含表示数据的业务逻辑和方式。 某些forms的这些数据中的一些可能会显示在视图中。 它也可以包含从某个源检索数据的逻辑。
  2. 控制器:作为视图和模型之间的连接。 查看调用控制器和控制器调用模型。 它基本上通知模型和/或视图适当地改变。
  3. 查看:处理UI部分。 与用户进行交互。

MVVM (模型视图视图模型)

ViewModel

  1. 这是观点状态的表示。
  2. 它保存在视图中显示的数据。
  3. 响应查看事件,即演示逻辑。
  4. 调用业务逻辑处理的其他function。
  5. 从不直接要求视图显示任何东西。

MVVM将视图模型添加到混合中。 这很重要,因为它允许您使用WPF的很多绑定方法,而无需将所有特定于UI的部分放在常规模型中。

我可能是错的,但我不确定MVVM是否真的迫使控制器进入混合。 我发现这个概念更符合: http : //martinfowler.com/eaaDev/PresentationModel.html 。 我认为人们select将其与MVC结合起来,而不是将其纳入模式。

根据我所知,MVVM映射到MVC的MV – 意味着在传统的MVC模式中,V不直接与M通信。在MVC的第二个版本中,M和V之间存在直接链接。MVVM似乎将与M和V通信相关的所有任务都耦合起来,并将它与C相分离。实际上,MVVM中仍然没有充分说明范围更大的应用程序工作stream程(或使用场景的实现)。 这是控制器的angular色。 通过从控制器中删除这些较低级别的方面,它们更清洁,并且使修改应用程序的使用场景和业务逻辑变得更加容易,也使控制器更加可重用。

MVC是一个受控环境,MVVM是一个被动环境。

在一个受控的环境中,你应该有更less的代码和一个共同的逻辑来源; 应始终居住在控制器内。 然而; 在networking世界中,MVC很容易分解成视图创build逻辑和视图dynamic逻辑。 创造活在服务器上,dynamic的生活在客户端上。 您将ASP.NET MVC与AngularJS结合在一起看到了很多,而服务器将创build一个View并传入一个Model并将其发送给客户端。 然后,客户端将与View进行交互,在这种情况下,AngularJS作为本地控制器进入。 一旦提交模型或新的模型被传回服务器控制器并处理。 (因此循环继续,并且在处理套接字或AJAX等时有很多其他的处理翻译,但在所有的体系结构是相同的。)

MVVM是一个被动环境,意味着你通常会编写代码(如触发器),这些代码将根据某个事件激活。 在MVVM茁壮成长的XAML中,这一切都可以通过内置的数据绑定框架轻松完成,但是如前所述,这可以在任何View上的任何系统上使用任何编程语言。 这不是MS特定的。 ViewModel会触发(通常是一个属性改变的事件),View会根据你创build的触发器做出反应。 这可以得到技术,但底线是视图是无状态的,没有逻辑。 它只是根据值改变状态。 而且,ViewModel是无状态的,只有很less的逻辑,而Models是基本上为零逻辑的状态,因为它们只应该保持状态。 我将其描述为应用程序状态(Model),状态翻译器(ViewModel),然后是视觉状态/交互(View)。

在MVC桌面或客户端应用程序中,您应该有一个Model,而Model应该被Controller使用。 基于该模型,控制器将修改视图。 视图通常与带有接口的控制器绑定,以便控制器可以使用各种视图。 在ASP.NET中,MVC的逻辑稍微落后于服务器,因为Controllerpipe理模型并将模型传递给选定的视图。 然后视图充满基于模型的数据,并具有自己的逻辑(通常是另一个MVC集合,例如用AngularJS完成的)。 人们会争论,并与应用程序MVC混淆,并尝试做到这一点维持该项目将最终成为一个灾难。 使用MVC时总是把逻辑和控制放在一个位置。 不要在视图后面的代码中(或者在通过JS的View中)写视图逻辑来容纳控制器或模型数据。 让控制器更改视图。 应该存在于View中的唯一逻辑是通过它所使用的接口来创build和运行的任何东西。 一个例子是提交一个用户名和密码。 无论桌面还是网页(客户端),只要View触发提交操作,控制器就应该处理提交过程。 如果做得正确,你总是可以轻松find你的MVC网站或本地应用程序的方式。

MVVM是我个人最喜欢的,因为它是完全被动的。 如果一个模型改变状态,ViewModel监听并翻译那个状态,就是这样! View然后侦听ViewModel进行状态改变,并且它也根据ViewModel的转换进行更新。 有些人称之为纯粹的MVVM,但实际上只有一个,我不在乎你是如何争论的,而且它始终是Pure MVVM,其中View完全没有逻辑。

下面是一个简单的例子:假设你想在一个button上按下一个菜单。 在MVC中,您将在界面中使用MenuPressed操作。 控制器会知道你什么时候点击菜单button,然后根据另一个接口方法(如SlideMenuIn)告诉视图在菜单中滑动。 往返是为了什么原因? 因为控制器决定你不能或想要做别的事情,这就是为什么。 除非主持人这么说,否则主持人应该负责视图和视图。 然而; 在MVVM中,animation中的幻灯片菜单应该内置在通用中,而不是被告知将其滑动到基于某个值的位置。 所以它监听ViewModel,当ViewModel说IsMenuActive = true(或者是)时,animation就会发生。 现在,就这么说,我想再提一点,真的很清楚,请注意。 IsMenuActive可能是不良的MVVM或ViewModeldevise。 当devise一个ViewModel时,你永远不应该假设一个View将会有任何特性,只是传递翻译后的模型状态。 这样,如果你决定改变视图来删除菜单,只是以其他方式显示数据/选项,ViewModel并不在意。 那么如何pipe理菜单? 当数据是有道理的,这是如何。 所以,一种方法是给Menu提供一个选项列表(可能是一个内部ViewModel的数组)。 如果该列表有数据,菜单就知道通过触发器打开,如果没有,则知道通过触发器隐藏。 你只需要在菜单中有数据或不在ViewModel中。 不要决定显示/隐藏在ViewModel中的数据..只需翻译模型的状态。 这种方式视图是完全反应和通用的,可以用在许多不同的情况。

如果你还没有熟悉每个架构,那么所有这些都可能是完全没有意义的,并且学习它会让你非常困惑,因为你会在网上发现很多不好的信息。

所以…要记住要做到这一点。 决定如何devise你的应用程序和紧贴IT。

如果你做MVC,那很好,那么确保你的Controller是可pipe理的并且完全控制你的View。 如果您有一个较大的视图,请考虑将控件添加到具有不同控制器的视图。 不要将这些控制器级联到不同的控制器。 非常令人沮丧的维护。 花点时间分别devise一些独立的组件,然后让控制器告诉模型提交或保存存储。 MVC中的理想依赖设置是View←Controller→Model或者ASP.NET(不要让我开始) Model←View→Controller→Model(其中Model可以是相同的,也可以是从Controller到View的完全不同的Model) …当然,在这一点上唯一需要了解Controller中View控制器的信息大部分是用于终点参考,以便知道在哪里传回一个Model。

如果你做MVVM,我保佑你的善良的灵魂,但花时间做正确的! 不要使用一个接口。 让你的视图根据值来决定它的外观。 使用模拟数据查看。 如果你最终有一个视图,显示你的菜单(按照这个例子),即使你不想在当时好。 你的观点正在发挥作用,根据价值观做出反应。 只需要添加一些更多的要求到你的触发器,以确保当ViewModel处于特定的转换状态时不会发生这种情况,或者命令ViewModel清空这个状态。 在您的ViewModel不要删除这与内部逻辑或者如果你决定从那里是否应该看到它。 请记住,您不能假定ViewModel中有菜单或不是。 最后,模型应该允许你改变和最有可能的存储状态。 This is where validation and all will occur; for example, if the Model can't modify the state then it will simply flag itself as dirty or something. When the ViewModel realizes this it will translate what's dirty, and the View will then realize this and show some information via another trigger. All data in the View can be binded to the ViewModel so everything can be dynamic only the Model and ViewModel has absolutely no idea about how the View will react to the binding. As a matter of fact the Model has no idea of a ViewModel either. When setting up dependencies they should point like so and only like so View → ViewModel → Model (and a side note here… and this will probably get argued as well but I don't care… DO NOT PASS THE MODEL to the VIEW. The View should not see a model period. I give a rats crack what demo you've seen or how you've done it, that's wrong.)

Here's my final tip… Look at a well designed, yet very simple, MVC application and do the same for an MVVM application. One will have more control with limited to zero flexibility while the other will have no control and unlimited flexibility.

A controlled environment is good for managing the entire application from a set of controllers or (a single source) while a reactive environment can be broken up into separate repositories with absolutely no idea of what the rest of the application is doing. Micro managing vs free management.

If I haven't confused you enough try contacting me… I don't mind going over this in full detail with illustration and examples.

At the end of the day we're all programmers and with that anarchy lives within us when coding… So rules will be broken, theories will change, and all of this will end up hog wash… But when working on large projects and on large teams, it really helps to agree on a design pattern and enforce it. One day it will make the small extra steps taken in the beginning become leaps and bounds of savings later.

Injecting Strongly Typed ViewModels into the View using MVC

  1. The controller is responsible for newing up the ViewModel and injecting it into the View. (for get requests)
  2. The ViewModel is the container for DataContext and view state such as the last selected item etc.
  3. The Model contains DB entities and is very close to the DB Schema it does the queries and filtering. (I like EF and LINQ for this)
  4. The Model should also consider repositories and or projection of results into strong types (EF has a great method… EF.Database.Select(querystring, parms) for direct ADO access to inject queries and get back strong types. This addresses the EF is slow argument. EF is NOT SLOW !
  5. The ViewModel gets the data and does the business rules and validation
  6. The controller on post back will cal the ViewModel Post method and wait for results.
  7. The controller will inject the newly updated Viewmodel to the View. The View uses only strong type binding .
  8. The view merely renders the data, and posts events back to the controller. (see examples below)
  9. MVC intercepts the inbound request and routes it to proper controller with strong data type

In this model there is no more HTTP level contact with the request or response objects as MSFT's MVC machine hides it from us.

In clarification of item 6 above (by request)…

Assume a ViewModel like this:

 public class myViewModel{ public string SelectedValue {get;set;} public void Post(){ //due to MVC model binding the SelectedValue string above will be set by MVC model binding on post back. //this allows you to do something with it. DoSomeThingWith(SelectedValue); SelectedValue = "Thanks for update!"; } } 

The controller method of the post will look like this (See below), note that the instance of mvm is automatically instanciated by the MVC binding mechanisms. You never have to drop down to the query string layer as a result! This is MVC instantiating the ViewModel for you based on the query strings!

 [HTTPPOST] public ActionResult MyPostBackMethod (myViewModel mvm){ if (ModelState.IsValid) { // Immediately call the only method needed in VM... mvm.Post() } return View(mvm); } 

Note that in order for this actionmethod above to work as you intend, you must have a null CTOR defined that intializes things not returned in the post. The post back must also post back name/value pairs for those things which changed. If there are missing name/value pairs the MVC binding engine does the proper thing which is simply nothing! If this happens you might find yourself saying "I'm losing data on post backs"…

The advantage of this pattern is the ViewModel does all the "clutter" work interfacing to the Model/Buisness logic, the controller is merely a router of sorts. It is SOC in action.

It surprises me that this is a highly voted answers without mentioning the origin of MVVM. MVVM is a popular term used in Microsoft community and it is originated from Martin Fowler's Presentation Model . So to understand the motive of the pattern and the differences with others, the original article about the pattern is the first thing to read.

Well, generally MVC is used in Web development and MVVM is most popular in WPF/Silverlight development. However, sometimes the web architecute might have a mix of MVC and MVVM.

For example: you might use knockout.js and in this case you will have MVVM on your client side. And your MVC's server side can also change. In the complex apps, nobody uses the pure Model. It might have a sense to use a ViewModel as a "Model" of MVC and your real Model basically will be a part of this VM. This gives you an extra abstraction layer.

MVVMC, or perhaps MVC+, seems to be a viable approach for enterprise as well as rapid application development. While it is nice to separate the UI from business and interaction logic, the 'pure' MVVM pattern and most available examples work best on singular views.

Not sure about your designs, but most of my applications, however, contain pages and several (reusable) views and thus the ViewModels do need to interact to some degree. Using the page as controller would defeat the purpose of the MVVM altogether, so not using a "VM-C" approach for the underlying logic might result in .. well .. challenging constructs as the application matures. Even in VB-6 most of us probably stopped coding business logic into the Button event and started 'relaying' commands to a controller, right? I recently looked at many emerging framworks on that topic; my favorite clearly is the Magellan (at codeplex) approach. Happy coding!

http://en.wikipedia.org/wiki/Model_View_ViewModel#References

From a practical point of view, MVC (Model-View-Controller) is a pattern. However, MVC when used as ASP.net MVC, when combined with Entity Framework (EF) and the "power tools" is a very powerful, partially automated approach for bringing databases, tables, and columns to a web-page, for either full CRUD operations or R (Retrieve or Read) operations only. At least as I used MVVM, the View Models interacted with models that depended upon business objects, which were in turn "hand-made" and after a lot of effort, one was lucky to get models as good as what EF gives one "out-of-the-box". From a practical programming point of view, MVC seems a good choice because it gives one lots of utility out-of-box, but there is still a potential for bells-and-whistles to be added.

Complementary to many of the responses given, I wanted to add some additional perspective from the Modern client-side web – or Rich Web Application point of view.

Indeed these days simple web sites and larger web applications are commonly built with many popular libraries such as Bootstrap. Built by Steve Sanderson, Knockout provides support for the MVVM pattern which mimics one of the most important behaviors in the pattern: data-binding through the View Model. With a little JavaScript, data and logic can be implemented that can then be added to page elements with simple data-bind HTML attributes, similar to using many of the features of Bootstrap . Together, these two libraries alone offer interactive content; and when combined with routing this approach can result in a simple-yet-powerful approach to building the Single Page Application .

Similarly, a Modern client-side framework such as Angular follows the MVC pattern by convention, but also adds a Service. Interestingly, it is touted as Model-View-Whatever (MVW). (See this post on Stack Overflow .)

Additionally, with the rise of Progressive web frameworks such as Angular 2, we're seeing a change in terminology and perhaps a new architectural pattern where Components comprise of a View or Template and interact with a Service – all of which can be contained in a Module; and a series of Modules makes up the application.

I used to think that MVC and MVVM are the same. Now because of the existence of Flux I can tell the difference:

In MVC, for each view in your app, you have a model and a controller, so I would call it view, view model, view controller. The pattern does not tell you how one view can communicate with another. Therefore, in different frameworks there are different implementations for that. For example there are implementations where controllers talk to each other whereas in other implementations there's another component that mediates between them. There are even implementations in which the view models communicate with each other, which is a break of the MVC pattern because the view model should only be accessed by the view controller.

In MVVM, you also have a view model for each component. The pattern does not specify how the heck the view should influence the view model, so usually most frameworks just include controller's functionality in the view model. However, MVVM does tell you that your view model's data should come from the model, which is the entire model that's not aware or custom to a specific view.

To demonstrate the difference, let's take Flux pattern. Flux pattern tells how different views in the app should communicate. Each view listens to a store and fires actions using the dispatcher. The dispatcher in turn tells all the stores about the action that was just made, and the stores update themselves. A store in Flux corresponds to the (general) model in MVVM. it's not custom to any specific view. So usually when people use React and Flux, each React component actually implements the MVVM pattern. When an action occurs, the view model calls the dispatcher, and finally it's getting updated according to the changes in the store, which is the model. You can't say that each component implements MVC because in MVC only the controller can update the view model. So MVVM can work with Flux together (MVVM handles the communication between the view and the view model, and Flux handles the communication between different views), whereas MVC can't work with Flux without breaking a key principle.

Interesting Posts