标准的"模型视图控制器"模式与Microsoft的模型/视图/ ViewModel模式之间是否存在差异?
在ASP.Net和Silverlight/WPF开发中,这两种模式以不同的方式出现.
对于ASP.Net,MVVM用于在视图中双向绑定数据.这通常是客户端实现(例如使用Knockout.js).另一方面,MVC是一种在服务器端分离关注点的方法.
对于Silverlight和WPF,MVVM模式更具有包容性,并且似乎可以替代MVC(或将软件组织成单独职责的其他模式).一个假设,经常出来这个模式,是,ViewModel
简单地更换控制器MVC
(如如果你可以只替换VM
为C
的缩写,所有会原谅)...
问题是:可以独立测试*,特别是在需要时可重用,视图模型不知道哪个视图显示它,但更重要的是不知道它的数据来自何处.
*注意:在实践中,控制器会从ViewModel中删除需要进行单元测试的大部分逻辑.然后,VM变成一个愚蠢的容器,几乎不需要测试.这是一件好事,因为VM只是设计师和编码器之间的桥梁,所以应该保持简单.
即使在MVVM中,控制器通常也会包含所有处理逻辑,并决定使用哪个视图模型在哪些视图中显示哪些数据.
从我们目前所看到的ViewModel模式的主要好处是从XAML代码隐藏中删除代码,使XAML编辑成为一个更独立的任务.我们仍然会在需要时创建控制器来控制(无双关语)我们应用程序的整体逻辑.
视图显示特定形状的数据.他们不知道数据来自哪里.
ViewModels 拥有某种形状的数据和命令,它们不知道数据或代码的来源或显示方式.
模型包含实际数据(各种上下文,存储或其他方法)
控制器监听和发布事件.控制器提供控制所见数据和位置的逻辑.控制器向ViewModel提供命令代码,以便ViewModel实际上可重用.
我们还注意到Sculpture代码生成框架实现了MVVM和类似于Prism的模式.它还广泛使用控制器来分离所有用例逻辑.
我已经开始了一个关于这个主题的博客,我将尽我所能添加.将MVCVM与通用导航系统相结合存在一些问题,因为大多数导航系统只使用视图和虚拟机,但我将在后面的文章中介绍它.
An additional benefit of using an MVCVM model is that only the controller objects need to exist in memory for the life of the application and the controllers contain mainly code and little state data (i.e. tiny memory overhead). This makes for much less memory-intensive apps than solutions where view-models have to be retained and it is ideal for certain types of mobile development (e.g. Windows Mobile using Silverlight/Prism/MEF). This does of course depend on the type of application as you may still need to retain the occasional cached VMs for responsiveness.
注意:这篇文章已被多次编辑,并没有专门针对所提出的狭隘问题,所以我已经更新了第一部分,现在也涵盖了这一点.在下面的评论中,大部分讨论仅涉及ASP.Net,而不是更广泛的图景.这篇文章旨在涵盖在Silverlight,WPF和ASP.Net中更广泛地使用MVVM,并尝试避免人们用ViewModel替换控制器.
我认为理解这些首字母缩略词的最简单方法是暂时忘掉它们.相反,考虑一下它们所源自的软件.它实际上归结为早期网络和桌面之间的差异.
第一个首字母缩写词MVC起源于网络.(是的,它可能曾经存在过,但网络是如何向大量的Web开发人员推广的.)想想数据库,HTML页面和代码.让我们稍微改进一下以获得MVC:对于»database«,让我们假设数据库加接口代码.对于»HTML pages«,我们假设HTML模板和模板处理代码.对于»code inbetween«,让我们假设代码将用户点击映射到可能影响数据库的操作,肯定会导致显示另一个视图.就是这样,至少为了这个比较的目的.
让我们保留这个网络内容的一个特征,不像现在这样,但是十年前它存在,当时JavaScript是一个卑微,卑鄙的烦恼,真正的程序员很好地避开了:HTML页面本质上是愚蠢和被动的.浏览器是瘦客户端,或者如果你愿意的话,是一个糟糕的客户端.浏览器中没有智能.整页重新加载规则.每次都会重新生成»view«.
让我们记住,这种网络方式虽然风靡一时,但与桌面相比却是非常落后的.如果您愿意,桌面应用程序是胖客户端或富客户端.(甚至像Microsoft Word这样的程序也可以被认为是某种客户端,文档的客户端.)他们是充满智慧的客户,充满了关于他们数据的知识.他们是有状态的.它们缓存了他们在内存中处理的数据.没有这样的废话作为整页重新加载.
这种丰富的桌面方式可能是第二个首字母缩略词起源于MVVM的地方.不要被字母所愚弄,因为C的遗漏仍然存在.他们需要.什么都没有被删除.我们只添加一件事:有状态,缓存在客户端上的数据(以及处理该数据的智能).该数据,实际上是客户端上的缓存,现在称为"ViewModel".它允许丰富的交互性.就是这样.
MVC =模型,控制器,视图=基本上是单向通信=差的交互性
MVVM =模型,控制器,缓存,视图=双向通信=丰富的交互性
我们可以看到,使用Flash,Silverlight,以及 - 最重要的是 - JavaScript,网络已经接受了MVVM.浏览器不能再被合法地称为瘦客户端.看看他们的可编程性.看看他们的记忆消耗.查看现代网页上的所有Javascript交互性.
就个人而言,我发现这个理论和首字母缩略词业务通过查看它在具体现实中所指的内容更容易理解.抽象概念是有用的,特别是在具体问题上展示时,所以理解可能会完整.
MVVM 模型 - 视图ViewModel类似于MVC,模型 - 视图控制器
控制器将替换为ViewModel.ViewModel位于UI层下方.ViewModel公开视图所需的数据和命令对象.您可以将此视为一个容器对象,该视图用于获取其数据和操作.ViewModel从模型中提取数据.
Russel East做了一个博客,详细讨论了 为什么MVVM与MVC不同
首先,MVVM是MVC模式的一个进程,它使用XAML来处理显示. 本文概述了两者的一些方面.
Model/View/ViewModel架构的主要推力似乎是在数据("模型")之上,还有另一层非可视组件("ViewModel"),它们更紧密地映射数据的概念到数据视图的概念("视图").它是View绑定的ViewModel,而不是Model直接绑定的ViewModel.
您可以在Windows环境中看到 MVVM模式的说明:
在Model-View-ViewModel设计模式中,应用程序由三个通用组件组成.
模型:这表示您的应用消耗的数据模型.例如,在图片共享应用程序中,此图层可能表示设备上可用的图片集以及用于读取和写入图片库的API.
视图:应用程序通常由多个UI页面组成.向用户显示的每个页面都是MVVM术语中的视图.视图是用于定义和设置用户看到的样式的XAML代码.模型中的数据将显示给用户,ViewModel的工作是根据应用程序的当前状态向UI提供此数据.例如,在图片共享应用程序中,视图将是向用户显示设备上的专辑列表,专辑中的图片以及可能向用户显示特定图片的另一个UI的UI.
ViewModel:ViewModel将数据模型或模型简单地绑定到应用程序的UI或视图.它包含用于管理模型中数据的逻辑,并将数据公开为XAML UI或视图可绑定的一组属性.例如,在图片共享应用程序中,ViewModel将公开一个专辑列表,并为每个专辑公开一个图片列表.UI不知道图片来自何处以及如何检索图片.它只知道ViewModel公开的一组图片并将其显示给用户.
我认为其中一个主要区别是在MVC中,你的V直接读取你的M,然后通过C来操作数据,而在MVVM中,你的VM充当M代理,并为你提供可用的功能V.
如果我没有充满垃圾,我很惊讶没有人创建混合,你的VM只是一个M代理,而C提供所有功能.
MVC是受控环境,MVVM是一个被动环境.
在受控环境中,您应该拥有更少的代码和共同的逻辑源; 它应始终存在于控制器内.然而; 在Web世界中,MVC很容易分为视图创建逻辑和视图动态逻辑.创建存在于服务器上,而动态存在于客户端上.ASP.NET MVC结合AngularJS可以看到很多,而服务器将创建一个View并传入Model并将其发送给客户端.然后,客户端将与View进行交互,在这种情况下,AngularJS将作为本地控制器进入.提交后,模型或新模型将传递回服务器控制器并进行处理.(因此循环继续,当使用套接字或AJAX等时,这种处理还有很多其他的翻译,但是在所有架构上都是相同的.)
MVVM是一个反应环境,意味着您通常会编写基于某些事件激活的代码(例如触发器).在MVAM蓬勃发展的XAML中,使用内置的数据绑定框架可以很容易地实现这一点.如上所述,这将适用于任何View中使用任何编程语言的任何系统.它不是MS特定的.触发ViewModel(通常是属性更改事件),View会根据您创建的任何触发器对其做出反应.这可以获得技术,但底线是View是无状态且没有逻辑.它只是根据值改变状态.此外,ViewModel是无状态的,逻辑非常少,而模型是具有基本零逻辑的状态,因为它们应该只保持状态.我将其描述为应用程序状态(Model),状态转换器(ViewModel),然后是可视状态/交互(View).
在MVC桌面或客户端应用程序中,您应该有一个Model,并且Controller应该使用Model.基于Model,控制器将修改View.视图通常与具有接口的控制器相关联,因此Controller可以使用各种视图.在ASP.NET中,MVC的逻辑在服务器上略微向后,因为Controller管理模型并将模型传递给选定的视图.然后,View将根据模型填充数据并拥有自己的逻辑(通常是另一个MVC集,例如使用AngularJS完成).人们会争论并将其与应用程序MVC混淆并试图做到这两点,此时维护项目最终将成为一场灾难.在使用MVC时,始终将逻辑和控制放在一个位置.不要在View后面的代码中(或通过JS for web)编写View逻辑来容纳Controller或Model数据.让Controller更改视图.应该存在于视图中的唯一逻辑是通过它正在使用的接口创建和运行所需的任何逻辑.一个例子是提交用户名和密码.无论是桌面还是网页(在客户端),只要View触发提交操作,Controller就应该处理提交过程.如果操作正确,您可以轻松找到适合您的MVC网站或本地应用程序.无论是桌面还是网页(在客户端),只要View触发提交操作,Controller就应该处理提交过程.如果操作正确,您可以轻松找到适合您的MVC网站或本地应用程序.无论是桌面还是网页(在客户端),只要View触发提交操作,Controller就应该处理提交过程.如果操作正确,您可以轻松找到适合您的MVC网站或本地应用程序.
MVVM个人最喜欢,因为它完全被动.如果模型更改状态,ViewModel将侦听并转换该状态,就是这样!然后,View正在侦听ViewModel以进行状态更改,并且它还会根据ViewModel的转换进行更新.有些人称之为纯粹的MVVM,但实际上只有一个,我不在乎你是如何争论它的,而且它始终是Pure MVVM,其中View完全没有逻辑.
这是一个很小的例子:假设你想要按下按钮上的菜单.在MVC中,您将在界面中执行MenuPressed操作.控制器将在您单击"菜单"按钮时知道,然后根据另一个接口方法(如SlideMenuIn)告诉"视图"在菜单中滑动.往返是什么原因?如果控制器决定你不能或不想做其他事情,那就是原因.除非控制器这样说,否则控制器应负责视图,视图无效.然而; 在MVVM中,动画中的幻灯片菜单应该是内置的和通用的,而不是被告知滑动它将基于某些值这样做.所以它会监听ViewModel,当ViewModel说,IsMenuActive = true(或者然而)动画会发生.现在,与此说我想提出另一点真的很清楚,请注意.IsMenuActive可能是BAD MVVM或ViewModel设计.在设计ViewModel时,您永远不应假设View将具有任何功能,只需传递已翻译的模型状态即可.这样,如果您决定更改View以删除菜单并仅以其他方式显示数据/选项,则ViewModel无关紧要.那么你将如何管理菜单?当数据有意义的时候.因此,一种方法是给菜单一个选项列表(可能是一个内部ViewModel数组).如果该列表包含数据,则Menu会知道通过触发器打开,如果没有,则它知道通过触发器隐藏.您只需在ViewModel中拥有菜单数据.不要决定在ViewModel中显示/隐藏该数据.简单地翻译模型的状态.通过这种方式,View是完全被动的和通用的,可以在许多不同的情况下使用.
所有这些可能完全没有意义,如果你还没有至少略微熟悉每个架构,并且学习它可能会非常混乱,因为你会在网上找到很多不好的信息.
所以...要记住要做到这一点的事情.预先确定如何设计您的应用程序和STICK TO IT.
如果你做了MVC,这很棒,那么请确保你的Controller是可管理的并完全控制你的View.如果您有一个大型View,请考虑向具有不同控制器的View添加控件.只是不要将这些控制器级联到不同的控制器.维护非常令人沮丧.花点时间分别设计一些可以作为单独组件工作的东西......并且总是让Controller告诉Model提交或持久存储.MVC的理想依赖设置是查看←控制器→模型 或ASP.NET(不要让我开始)模型←查看↔控制器→模型(模型可以是相同的或完全不同的模型从控制器到视图)...当然,此时唯一需要知道Controller in View的内容主要是针对端点引用,以了解返回模型的位置.
如果你做MVVM,我会祝福你的善良灵魂,但要花时间去做吧!不要使用接口.让您的View根据值决定它的外观.使用模拟数据查看视图.如果您最终拥有一个显示菜单的视图(根据示例),即使您当时不想要它,也可以.您的观点正在按预期工作,并根据应有的价值做出反应.只需在触发器中添加一些要求,以确保在ViewModel处于特定转换状态时不发生这种情况,或者命令ViewModel清空此状态.在您的ViewModel中,请勿使用内部逻辑删除它,就像您从那里决定View是否应该看到它一样.请记住,您不能假设ViewModel中有菜单.最后,模型应该只允许您更改并最有可能存储状态.这是验证和所有将发生的地方; 例如,如果模型不能修改状态,那么它将简单地标记为脏或其他东西.当ViewModel实现这一点时,它将翻译脏的内容,然后View将实现此功能并通过另一个触发器显示一些信息.视图中的所有数据都可以绑定到ViewModel,因此一切都可以是动态的,只有Model和ViewModel完全不知道View将如何对绑定做出反应.事实上,模型也不知道ViewModel.在设置依赖项时,它们应该像这样指向并且只是这样 修改状态然后它会简单地将自己标记为脏或其他东西.当ViewModel实现这一点时,它将翻译脏的内容,然后View将实现此功能并通过另一个触发器显示一些信息.视图中的所有数据都可以绑定到ViewModel,因此一切都可以是动态的,只有Model和ViewModel完全不知道View将如何对绑定做出反应.事实上,模型也不知道ViewModel.在设置依赖项时,它们应该像这样指向并且只是这样 修改状态然后它会简单地将自己标记为脏或其他东西.当ViewModel实现这一点时,它将翻译脏的内容,然后View将实现此功能并通过另一个触发器显示一些信息.视图中的所有数据都可以绑定到ViewModel,因此一切都可以是动态的,只有Model和ViewModel完全不知道View将如何对绑定做出反应.事实上,模型也不知道ViewModel.在设置依赖项时,它们应该像这样指向并且只是这样 视图中的所有数据都可以绑定到ViewModel,因此一切都可以是动态的,只有Model和ViewModel完全不知道View将如何对绑定做出反应.事实上,模型也不知道ViewModel.在设置依赖项时,它们应该像这样指向并且只是这样 视图中的所有数据都可以绑定到ViewModel,因此一切都可以是动态的,只有Model和ViewModel完全不知道View将如何对绑定做出反应.事实上,模型也不知道ViewModel.在设置依赖项时,它们应该像这样指向并且只是这样查看→ViewModel→模型 (以及此处的侧面说明......这也可能会受到争议,但我不在乎......不要将模型传递给视图.视图不应该看到模型时期.我让老鼠破解你所见过的演示或你是怎么做的,这是错的.)
这是我的最后一个提示......看看一个设计良好但非常简单的MVC应用程序,并为MVVM应用程序执行相同的操作.一个人将拥有更多的控制权,灵活性有限,而另一个则没有控制权和无限的灵活性.
受控环境适用于从一组控制器或(单一来源)管理整个应用程序,而被动环境可以分解为单独的存储库,完全不知道应用程序的其余部分在做什么.微管理与免费管理.
如果我没有让你感到困惑,请尝试与我联系......我不介意通过插图和示例全面详细介绍.
在一天结束的时候,我们都是程序员,并且在编码时我们内心仍然存在无政府状态...所以规则将被打破,理论将会发生变化,所有这一切都将最终消耗殆尽...但是在大型工作时项目和大型团队,实际上有助于就设计模式达成一致并加以实施.有一天,它会在一开始就采取一些额外的小步骤,以后可以实现储蓄的跨越式发展.
简单的区别:(受Yaakov的Coursera AngularJS课程的启发)
MVC(模型视图控制器)
模型:模型包含数据信息.不调用或使用Controller和View.包含业务逻辑和表示数据的方式.某些形式的某些数据可能会显示在视图中.它还可以包含从某些源检索数据的逻辑.
控制器:充当视图和模型之间的连接.查看调用Controller和Controller调用模型.它基本上通知模型和/或视图以适当地改变.
查看:处理UI部分.与用户互动.
MVVM(模型视图视图模型)
ViewModel:
它是视图状态的表示.
它包含在视图中显示的数据.
响应视图事件,即表示逻辑.
调用业务逻辑处理的其他功能.
永远不要直接要求视图显示任何内容.
MVVM是Presentation Model模式的一种改进(有争议).我说有争议,因为唯一的区别在于WPF如何提供进行数据绑定和命令处理的能力.
viewmodel是用户界面元素的"抽象"模型.它必须允许您以非可视方式执行视图中的命令和操作(例如,对其进行测试).
如果您使用过MVC,那么您可能有时会创建模型对象来反映视图的状态,例如,显示和隐藏某些编辑对话框等.在这种情况下,您使用的是viewmodel.
MVVM模式只是将该实践概括为所有UI元素.
并且它不是Microsoft模式,附加的是WPF/Silverlight数据绑定特别适合使用此模式.但是,例如,没有什么能阻止你将它用于java服务器面.
对于那些不太熟悉建筑模式主题的人来说,其他答案可能并不容易理解.对应用程序架构不熟悉的人可能想知道它的选择如何影响她在实践中的应用程序以及社区中所有的大惊小怪.
为了阐明上述内容,我编写了涉及MVVM,MVP和MVC的剧本.故事开始于用户点击电影搜索应用程序中的"查找"按钮...:
用户:点击......
观点:那是谁?[ MVVM | MVP | MVC ]
用户:我刚刚点击了搜索按钮......
查看:好的,等一下...... [ MVVM | MVP | MVC ]
(查看调用ViewModel | Presenter | Controller ...)[ MVVM | MVP | MVC ]
查看:嘿ViewModel | 主持人 | 控制器,用户刚刚点击搜索按钮,我该怎么办?[ MVVM | MVP | MVC ]
ViewModel | 主持人 | 控制器:嘿View,该页面上有搜索词吗?[ MVVM | MVP | MVC ]
观点:是的,......这里是......"钢琴"[ MVVM | MVP | MVC ]
-这是之间最重要的区别MVVM和MVP | MVC ---
主持人:谢谢观看,...同时我正在查找模型上的搜索词,请向他/她显示进度条[ MVP | MVC ]
(Presenter | Controller正在调用Model ...)[ MVP | MVC ]
ViewController:谢谢,我将在模型上查找搜索词,但不会直接更新.相反,如果有任何结果,我将触发searchResultsListObservable事件.所以你最好观察一下.[ MVVM ]
(在观察searchResultsListObservable中的任何触发器时,View认为它应该向用户显示一些进度条,因为ViewModel不会在其上与之对话)
------------------------------
ViewModel | 主持人 | 控制器:嘿模型,你对这个搜索词有什么匹配吗?:"piano"[ MVVM | MVP | MVC ]
型号:Hey ViewModel | 主持人 | 控制器,让我查一下...... [ MVVM | MVP | MVC ]
(模型正在对电影数据库进行查询......)[ MVVM | MVP | MVC ]
( 过了一会儿 … )
----这是MVVM,MVP和MVC之间的分歧 -----
模型:我找到了一个列表,ViewModel | 演讲者,这里是JSON"[{"name":"Piano Teacher","year":2001},{"name":"Piano","year":1993}]"[ MVVM | MVP ]
型号:有一些结果可用,控制器.我在我的实例中创建了一个字段变量,并用结果填充它.它的名字是"searchResultsList"[ MVC ]
(演示者 | 控制器感谢模型并返回视图)[ MVP | MVC ]
主持人:感谢等待观看,我找到了一份匹配结果列表,并以一种可呈现的格式排列:["Piano Teacher 2001","Piano 1993"].也请现在隐藏进度条[ MVP ]
控制器:感谢您等待View,我向Model询问了您的搜索查询.它说它找到了一个匹配结果列表,并将它们存储在其实例中名为"searchResultsList"的变量中.你可以从那里得到它.也请现在隐藏进度条[ MVC ]
ViewModel:任何关于searchResultsListObservable的观察者都会收到有关这种新列表的通知:["Piano Teacher 2001","Piano 1993"].[ MVVM ]
观点:非常感谢Presenter [ MVP ]
查看:谢谢" 控制器 "[ MVC ](现在视图质疑自己:我应该如何呈现从模型中获得的结果给用户?电影的制作年份应该是第一个还是最后一个......?)
查看:哦,searchResultsListObservable中有一个新的触发器......好的,有一个可呈现的列表,现在我只需要在列表中显示它.我现在也应该隐藏进度条,因为我有结果.[ MVVM ]
如果您有兴趣,我在这里写了一系列文章,通过实现电影搜索Android应用程序来比较MVVM,MVP和MVC.
控制器负责新建ViewModel并将其注入View.(获取请求)
ViewModel是DataContext的容器和视图状态,例如最后选择的项目等.
模型包含数据库实体,非常接近数据库模式,它执行查询和过滤.(我喜欢EF和LINQ)
模型还应该考虑存储库和/或将结果投影到强类型中(EF有一个很好的方法... EF.Database.Select(查询字符串,参数),用于直接ADO访问以注入查询并返回强类型.这解决了EF是一个缓慢的论点.EF不是很慢!
ViewModel获取数据并执行业务规则和验证
回发后的控制器将调用ViewModel Post方法并等待结果.
控制器将新更新的Viewmodel注入View.View 仅使用强类型绑定.
该视图仅呈现数据,并将事件发回给控制器.(见下面的例子)
MVC拦截入站请求并将其路由到具有强数据类型的适当控制器
在这个模型中,没有更多的HTTP级别与请求或响应对象联系,因为MSFT的MVC机器将它隐藏起来.
澄清上述第6项(按要求)......
假设一个像这样的ViewModel:
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!"; } }
帖子的控制器方法将如下所示(见下文),请注意mvm的实例由MVC绑定机制自动实例化.因此,您永远不必下拉到查询字符串层!这是MVC根据查询字符串为您实例化ViewModel!
[HTTPPOST] public ActionResult MyPostBackMethod (myViewModel mvm){ if (ModelState.IsValid) { // Immediately call the only method needed in VM... mvm.Post() } return View(mvm); }
请注意,为了使上述此操作方法按预期工作,您必须定义一个空CMOR,以初始化帖子中未返回的内容.回发还必须回发那些已更改的内容的名称/值对.如果缺少名称/值对,MVC绑定引擎会做正确的事情,这根本就不算什么!如果发生这种情况,您可能会发现自己在说"我正在丢失帖子上的数据"......
这种模式的优点是ViewModel完成了与Model/Buisness逻辑接口的所有"混乱"工作,控制器只是一种路由器.SOC正在行动中.
MVVM将视图模型添加到组合中.这很重要,因为它允许您使用WPF的许多绑定方法,而无需将所有UI特定部分放在常规模型中.
我可能错了,但我不确定MVVM是否真的迫使控制器进入组合.我发现这个概念更符合:http://martinfowler.com/eaaDev/PresentationModel.html.我认为人们选择将它与MVC结合起来,而不是它内置于模式中.
据我所知,MVVM映射到MVC的MV - 意味着在传统的MVC模式中,V不直接与M通信.在MVC的第二个版本中,M和V之间存在直接链接.MVVM似乎采取了与M和V通信相关的所有任务,并将其耦合以将其与C分离.实际上,仍有更大范围的应用程序工作流程(或使用方案的实现)在MVVM中未完全考虑.这是控制器的作用.通过从控制器中删除这些较低级别的方面,它们更清晰,可以更轻松地修改应用程序的使用场景和业务逻辑,同时使控制器更易于重用.
令我惊讶的是,这是一个高度投票的答案,没有提到MVVM 的起源.MVVM是Microsoft社区中使用的一个流行术语,它源自 Martin Fowler的Presentation Model.因此,要了解模式的动机和与他人的差异,关于模式的原始文章是首先要阅读的.
嗯,通常MVC用于Web开发,MVVM在WPF/Silverlight开发中最受欢迎.但是,有时web架构可能混合使用MVC和MVVM.
例如:您可能使用knockout.js,在这种情况下,您将在客户端使用MVVM.而你的MVC的服务器端也可以改变.在复杂的应用程序中,没有人使用纯模型.将ViewModel用作MVC的"模型"可能是有意义的,您的真实模型基本上将成为此VM的一部分.这为您提供了额外的抽象层.