关于模型视图控制器:MVC和MVVM之间有什么区别?

What is the difference between MVC and MVVM?

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


MVC/MVVM不是一个非此即彼的选择。

在ASP.NET和Silverlight/WPF开发中,这两种模式以不同的方式突然出现。

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

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

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

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

*注意:在实践中,控制器从视图模型中删除了大部分需要单元测试的逻辑。然后,虚拟机变成了一个不需要测试(如果有的话)的哑容器。这是一件好事,因为虚拟机只是设计师和编码人员之间的桥梁,所以应该保持简单。

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

从我们目前看到的情况来看,viewModel模式的主要好处是从后面的XAML代码中删除代码,使XAML编辑成为一项更加独立的任务。我们仍然在需要时创建控制器来控制(没有双关语)应用程序的整体逻辑。

我们遵循的基本MVCVM指南如下:

  • 视图显示特定形状的数据。他们不知道数据来自哪里。
  • 视图模型拥有特定的数据和命令形状,它们不知道数据或代码来自何处,也不知道如何显示。
  • 模型保存实际数据(各种上下文、存储或其他方法)
  • 控制器监听并发布事件。控制器提供控制所见数据和位置的逻辑。控制器向viewModel提供命令代码,以便viewModel实际上是可重用的。

我们还注意到,sculpture code gen框架实现了MVVM和类似于prism的模式,它还广泛地使用控制器来分离所有用例逻辑。

不要假设控制器被视图模型废弃。

我已经开始写一篇关于这个主题的博客,我会尽我所能添加到其中。将MVCVM与通用导航系统结合起来存在一些问题,因为大多数导航系统只使用视图和虚拟机,但我将在后面的文章中讨论这一点。

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

注意:这篇文章已经被编辑了很多次,并没有专门针对所问的狭隘问题,所以我更新了第一部分,现在也涵盖了这一点。在下面的评论中,大多数讨论只与ASP.NET有关,而与更广阔的前景无关。这篇文章旨在涵盖MVVM在Silverlight、WPF和ASP.NET中的广泛使用,并试图阻止人们用ViewModel替换控制器。


我认为理解这些缩略语的最简单方法就是暂时忘记它们。相反,想想他们最初使用的软件,每个软件。归根结底,这就是早期网络和桌面的区别。

第一个首字母缩略词MVC源自网络。(是的,它可能曾经存在过,但是网络是它如何普及到广大的网络开发者中的。)想想数据库、HTML页面和中间的代码。让我们对这个进行一点改进,以到达MVC:for?数据库?,让我们假设数据库加上接口代码。为了什么?HTML页面?,让我们假设HTML模板加上模板处理代码。为了什么?代码介于两者之间?,让我们假设代码映射用户单击到操作,可能会影响数据库,肯定会导致显示另一个视图。就是这样,至少在这个比较中是这样。

让我们保留一下这个web东西的一个特性,不是像现在这样,而是像十年前那样,当javascript是一个低级的、可鄙的烦恼时,真正的程序员很好地避开了它:HTML页面本质上是愚蠢和被动的。浏览器是一个瘦客户机,或者如果你愿意的话,是一个糟糕的客户机。浏览器中没有智能。整页重新加载规则。这个?视野?每次都会重新生成。

让我们记住,这种网络方式,尽管非常流行,但与桌面相比,却是非常落后的。桌面应用程序是胖客户端,或者富客户端,如果你愿意的话。(即使是像Microsoft Word这样的程序也可以被看作是某种客户机,文档客户机。)他们是充满智慧的客户机,对自己的数据充满了解。它们是庄严的。它们将处理的数据缓存在内存中。没有像重新加载整页这样的垃圾。

这种丰富的桌面方式可能是第二个首字母缩略词mvvm的发源地。不要被字母愚弄,不要被C的省略所愚弄。控制器还在那里。他们应该是。任何东西都不会被移除。我们只添加了一件事:状态性、客户机上缓存的数据(以及处理该数据的IT智能)。这些数据,本质上是客户机上的缓存,现在被调用了?ViewModel?它允许丰富的交互性。就是这样。

  • MVC=模型、控制器、视图=基本上是单向通信=交互性差
  • mvvm=模型、控制器、缓存、视图=双向通信=丰富的交互性

我们可以看到,通过Flash、Silverlight和(最重要的)javascript,网络已经接受了MVVM。浏览器不能再被合法地称为瘦客户机。看看他们的可编程性。看看他们的记忆力消耗。看看现代网页上所有的javascript交互。

就我个人而言,我发现这个理论和首字母缩略词业务更容易理解,通过查看它在具体现实中指的是什么。抽象概念是有用的,尤其是在具体问题上演示时,理解可能会是一个完整的循环。

nbsp;


MVVM模型视图模型类似于MVC,模型视图控制器

控制器将替换为ViewModel。视图模型位于UI层的下面。视图模型公开视图所需的数据和命令对象。您可以将其视为一个容器对象,视图将从中获取其数据和操作。ViewModel从模型中提取其数据。

Russel East在一篇博客中详细讨论了为什么MVVM不同于MVC


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

The main thrust of the Model/View/ViewModel architecture seems to be that on top of the data ("the Model"), there’s another layer of non-visual components ("the ViewModel") that map the concepts of the data more closely to the concepts of the view of the data ("the View"). It’s the ViewModel that the View binds to, not the Model directly.


您可以在Windows环境中看到MVVM模式的说明:

在模型视图视图模型设计模式中,应用程序由三个通用组件组成。enter image description here

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

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

  • 视图模型:视图模型将数据模型或简单的模型与应用程序的UI或视图相关联。它包含用于管理模型中数据的逻辑,并将数据作为XAML UI或视图可以绑定到的一组属性公开。例如,在图片共享应用程序中,ViewModel将公开相册列表,并且对于每个相册公开图片列表。用户界面不确定图片的来源和检索方式。它只知道一组由ViewModel显示的图片,并将它们显示给用户。


我认为主要的区别之一是,在MVC中,您的V直接读取M,并通过C来操作数据,而在MVVM中,您的VM充当M代理,并向V提供可用的功能。

如果我不是一个垃圾,我很惊讶没有人创建了一个混合体,你的虚拟机只是一个M代理,C提供了所有的功能。


简单区别:(灵感来源于亚科夫的课程《安古拉吉斯课程》)

enter image description here

MVC(模型视图控制器)

  • 模型:模型包含数据信息。不调用或使用控制器和视图。包含业务逻辑和表示数据的方法。有些数据以某种形式显示在视图中。它还可以包含从某个源检索数据的逻辑。
  • 控制器:作为视图和模型之间的连接。视图调用控制器,控制器调用模型。它基本上通知模型和/或视图进行适当的更改。
  • 视图:处理UI部件。与用户交互。
  • MVVM(模型视图模型)

    ViewModel:

  • 它是视图状态的表示。
  • 它保存在视图中显示的数据。
  • 响应视图事件,即表示逻辑。
  • 调用业务逻辑处理的其他功能。
  • 不要直接要求视图显示任何内容。

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


    MVC是一个受控环境,MVVM是一个反应性环境。好的。

    在受控环境中,您应该拥有更少的代码和一个通用的逻辑源;它应该始终位于控制器中。然而,在Web世界中,MVC很容易被划分为视图创建逻辑和视图动态逻辑。创建在服务器上,动态在客户机上。在ASP.NET MVC和AngularJS的结合中,您可以看到很多这样的情况,而服务器将创建一个视图并传入一个模型并将其发送给客户机。然后客户端将与视图交互,在这种情况下,AngularJS将作为本地控制器进入到。一旦提交了模型或一个新模型,它就会传回服务器控制器并进行处理。(因此,在使用套接字或Ajax等时,这种处理方式仍有很多其他翻译,但总体架构是相同的。)好的。

    MVVM是一个反应式环境,意味着您通常会编写代码(如触发器),这些代码将根据某些事件激活。在MVVM蓬勃发展的XAML中,这一切都可以通过内置的数据绑定框架轻松完成,但如前所述,这可以在任何视图下的任何系统上使用任何编程语言。它不是MS特定的。viewModel触发(通常是一个属性更改事件),视图根据您创建的任何触发器对其进行响应。这可以从技术上得到,但底线是视图是无状态的,没有逻辑。它只是根据值改变状态。此外,视图模型是无状态的,几乎没有逻辑,并且模型本质上是零逻辑的状态,因为它们应该只维护状态。我将其描述为应用程序状态(模型)、状态转换器(视图模型),然后是可视状态/交互(视图)。好的。

    在MVC桌面或客户端应用程序中,您应该有一个模型,并且该模型应该由控制器使用。根据模型,控制器将修改视图。视图通常与具有接口的控制器绑定,以便控制器可以处理各种视图。在ASP.NET中,当控制器管理模型并将模型传递给选定视图时,MVC的逻辑在服务器上稍微向后。然后,该视图将填充基于模型的数据,并具有自己的逻辑(通常是另一个MVC集,如使用AngularJS完成)。人们会争论这个问题,并将其与应用程序MVC混淆,并尝试在维护项目的时候两者都会最终成为一场灾难。使用MVC时,始终将逻辑和控制放在一个位置。不要在视图后面的代码中(或通过JSforWeb在视图中)编写视图逻辑来容纳控制器或模型数据。让控制器更改视图。唯一应该存在于视图中的逻辑是通过使用的接口创建和运行所需的一切。例如,提交用户名和密码。无论是桌面还是网页(在客户端),控制器都应在视图触发提交操作时处理提交过程。如果做的正确,你总是可以找到你的方式周围的MVC网站或本地应用程序容易。好的。

    MVVM是我个人最喜欢的,因为它是完全反应式的。如果模型改变了状态,那么viewModel就会监听并转换该状态,就这样!!!!然后,视图将侦听状态更改的ViewModel,并根据来自ViewModel的转换进行更新。有些人称它为纯MVVM,但实际上只有一个,我不在乎你怎么说,它总是纯MVVM,视图中绝对没有逻辑。好的。

    这里有一个很小的例子:假设你想要一个菜单滑入按钮按下。在MVC中,您的界面中将有一个menupressed操作。控制器将知道何时单击菜单按钮,然后根据另一种界面方法(如slide menu in)告诉视图在菜单中滑动。往返旅行是什么原因?如果管制员决定你不能或想做其他事情,那就是原因。控制器应该负责视图,除非控制器这么说,否则视图不做任何事情。然而,在mvvm中,动画中的幻灯片菜单应该是内置的和通用的,而不是被告知根据某个值滑入幻灯片菜单。所以它会监听viewModel,当viewModel说ismenuActive=true时(或者无论如何),动画就会发生。现在,有了这句话,我想再明确一点,请大家注意。IsmenuActive可能是错误的MVVM或ViewModel设计。在设计一个视图模型时,您不应该假定一个视图将具有任何特性,并且只传递转换后的模型状态。这样,如果您决定更改视图以删除菜单并以另一种方式显示数据/选项,则ViewModel不在乎。那么您将如何管理菜单呢?当数据有意义时,就是这样。因此,一种方法是给菜单一个选项列表(可能是一个内部视图模型数组)。如果这个列表有数据,那么菜单知道通过触发器打开,如果没有,那么它知道通过触发器隐藏。您只需要为菜单提供数据,或者不在视图模型中。不要决定在视图模型中显示/隐藏该数据。只需转换模型的状态。通过这种方式,视图是完全反应的和通用的,可以在许多不同的情况下使用。好的。

    如果你还不熟悉每一种体系结构的话,所有这些都可能毫无意义,而且你会发现网络上有很多不好的信息,这会让你很困惑。好的。

    所以…要想把这件事做好要牢记在心。提前决定如何设计应用程序并坚持下去。好的。

    如果您使用MVC,这很好,那么请确保您的控制器是可管理的,并且完全控制您的视图。如果视图很大,请考虑向具有不同控制器的视图添加控件。只是不要把这些控制器级联到不同的控制器上。很难维持。花点时间,以一种可以作为独立组件工作的方式单独设计事物…并且始终让控制器告诉模型提交或持久存储。MVC的理想依赖项设置是View←Controller→Model或with ASP.NET(Don't get me started)Model←View?控制器→模型(模型可以是同一个或完全不同的模型,从控制器到视图)…当然,此时唯一需要了解的控制器在视图中主要是端点引用,以了解返回到哪里传递模型。好的。

    如果你做了MVVM,我会祝福你善良的灵魂,但要花时间去做正确的事情!不要为一个使用接口。让您的视图根据值来决定它的外观。使用模拟数据处理视图。如果你最终看到的是一个显示菜单的视图(如示例所示),即使当时你不想要它,那就好了。您的视图正在按它应该的方式工作,并根据它应该的值进行响应。只需向触发器添加更多的需求,以确保当ViewModel处于特定的转换状态时不会发生这种情况,或者命令ViewModel清空此状态。在您的视图模型中,不要用内部逻辑删除这个,就像您要从中决定视图是否应该看到它一样。请记住,您不能假定视图模型中是否存在菜单。最后,模型应该只允许您更改和存储状态。这就是验证和所有验证发生的地方;例如,如果模型不能修改状态,那么它将简单地将自己标记为脏的或其他东西。当视图模型意识到这一点时,它将转换脏的内容,然后视图将实现这一点,并通过另一个触发器显示一些信息。视图中的所有数据都可以绑定到ViewModel,因此所有数据都可以是动态的,只有模型和ViewModel完全不知道视图对绑定的反应。事实上,模型也不知道视图模型。在设置依赖项时,它们应该指向类似的,并且只类似于"视图"?"视图模型"?"模型"(这里还有一个旁注…这可能也会引起争论,但我不在乎…不要将模型传递给视图。视图不应看到模型周期。我给一只老鼠解释一下你看到了什么样的演示或者你是怎么做的,这是错误的。)好的。

    这是我最后的建议…看看一个设计良好但非常简单的MVC应用程序,并为MVVM应用程序做同样的事情。一个将有更多的控制,限制为零灵活性,而另一个将没有控制和无限的灵活性。好的。

    受控环境有助于从一组控制器或(单个源)管理整个应用程序,而反应性环境可以分解为单独的存储库,而完全不知道应用程序的其余部分在做什么。微观管理与自由管理。好的。

    如果我没有足够的迷惑你,试着联系我…我不介意用插图和例子详细地讨论这个问题。好的。

    在一天结束的时候,我们都是程序员,在编码的时候,无政府状态就存在于我们体内……所以规则会被打破,理论会改变,所有这些都会被彻底洗劫…但在大型项目和大型团队中工作时,在设计模式上达成一致并加以实施确实有助于实现。总有一天,它会使在开始时采取的一些额外的小步骤在以后成为储蓄的飞跃。好的。好啊。


    ViewModel是用户界面元素的"抽象"模型。它必须允许您以非可视方式(例如测试)执行视图中的命令和操作。

    如果您使用了MVC,您可能有时会发现创建模型对象以反映视图的状态很有用,例如显示和隐藏一些编辑对话框等。在这种情况下,您使用的是ViewModel。

    MVVM模式只是该实践对所有UI元素的概括。

    它不是微软模式,附录是WPF/Silverlight数据绑定特别适合于使用这个模式。但是,没有什么能阻止您使用Java服务器面对它。


    MVVM将视图模型添加到组合中。这一点很重要,因为它允许您使用大量的WPF绑定方法,而不需要将所有特定于UI的部分放入常规模型中。

    我可能错了,但我不确定MVVM是否真的迫使控制器进入混合状态。我发现这个概念更符合:http://martinfowler.com/eaadev/presentationmodel.html。我认为人们选择将它与MVC结合起来,而不是将它内置到模式中。


    使用MVC将强类型的ViewModel注入视图

  • 控制器负责更新视图模型并将其注入视图中。(用于GET请求)
  • ViewModel是DataContext和视图状态(如最后选定的项等)的容器。
  • 该模型包含数据库实体,并且非常接近数据库模式,它执行查询和筛选。(我喜欢EF和LINQ)
  • 该模型还应考虑存储库和或结果投影到强类型(EF有一个很好的方法…选择(querystring,parms)作为ADO直接访问,以插入查询并返回强类型。这解决了ef is slow参数。EF并不慢!
  • ViewModel获取数据并执行业务规则和验证
  • 后置控制器将校准ViewModel后置方法并等待结果。
  • 控制器将把新更新的视图模型注入到视图中。视图只使用强类型绑定。
  • 视图只呈现数据,并将事件发回控制器。(见下例)
  • MVC拦截入站请求并将其路由到具有强数据类型的适当控制器
  • 在这个模型中,不再有与请求或响应对象的HTTP级联系,因为MSFT的MVC机器将其隐藏起来。

    在上述第6项的澄清中(按要求)

    假设一个这样的视图模型:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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!";
     }
    }

    post的controller方法如下(见下文),请注意,MVM的实例由MVC绑定机制自动启动。因此,您不必下拉到查询字符串层!这是MVC根据查询字符串为您实例化ViewModel!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [HTTPPOST]  
    public ActionResult MyPostBackMethod (myViewModel mvm){
             if (ModelState.IsValid)
            {
                   // Immediately call the only method needed in VM...
                   mvm.Post()
            }
          return View(mvm);
    }

    请注意,为了让上面的actionMethod按您的意愿工作,必须定义一个空的ctor,该ctor用于初始化post中未返回的内容。回发还必须为更改的内容回发名称/值对。如果缺少名称/值对,MVC绑定引擎将执行正确的操作,而这仅仅是一件微不足道的事情!如果发生这种情况,你可能会发现自己在说"我正在失去回邮数据"…

    这种模式的优点是viewModel完成了与模型/业务逻辑接口的所有"杂乱"工作,控制器只是一个各种各样的路由器。这是SOC的行动。


    让我惊讶的是,这是一个投票率很高的答案,没有提到MVVM的起源。MVVM是微软社区常用的一个术语,它起源于马丁·福勒的表示模型。因此,要了解模式的动机以及与其他模式的差异,首先要阅读关于模式的原始文章。


    据我所知,m v v v m映射到m v c的m v,这意味着在传统的m v c模式中,v不直接与m通信。在m v c的第二个版本中,m和v之间存在直接链接。m v v v m似乎承担了与m和v通信相关的所有任务,并将其耦合以将其与c分离。实际上,仍然存在在MVVM中没有完全考虑的更大范围的应用程序工作流(或使用场景的实现)。这是控制器的角色。通过从控制器中删除这些较低级别的方面,它们更干净,更容易修改应用程序的使用场景和业务逻辑,也使控制器更易于重用。


    对于一个不太熟悉体系结构模式主题的人来说,其他的答案可能不容易理解。一些对应用程序架构不熟悉的人可能想知道它的选择如何影响她的应用程序在实践中的应用程序,以及社区中所有的麻烦是什么。

    为了阐明以上几点,我编了一部涉及MVVM、MVP和MVC的剧本。故事开始于用户点击电影搜索应用程序中的"查找"按钮…:

    用户:点击…

    视图:那是谁?[MVVM] MVP MVC]

    用户:我刚刚点击了搜索按钮…

    视图:好的,稍等……[MVVM] MVP MVC]

    (视图调用ViewModel Presenter Controller…)[MVVM MVP MVC]

    视图:嘿,viewmodel presenter controller,一个用户刚刚点击了搜索按钮,我该怎么做?[MVVM] MVP MVC]

    viewmodel presenter controller:嘿,view,那个页面上有搜索词吗?[MVVM] MVP MVC]

    视图:是的,…在这里……"钢琴"[MVVM MVP MVC]

    --这是MVVM和MVP MVC之间最重要的区别---

    演示者:谢谢视图,…同时我正在查找模型上的搜索词,请给他/她显示一个进度条[MVP MVC]

    (演示者控制器正在调用模型…)[MVP MVC]

    viewcontroller:谢谢,我将在模型上查找搜索词,但不会直接更新您。相反,如果有任何结果,我将触发SearchResultsListobservable事件。所以你最好观察一下。[MVVM]

    (当观察searchresultsilstobservable中的任何触发器时,视图认为它应该向用户显示一些进度条,因为ViewModel不会就此与之交谈)

    ——————————————————————--

    viewmodel presenter controller:嘿,model,你有这个搜索词的匹配项吗?:"钢琴"[MVVM MVP MVC]

    模型:嘿,viewmodel presenter controller,让我检查一下…[MVVM MVP MVC]

    (模型正在查询电影数据库…)[MVVM MVP MVC]

    (过了一会儿…)

    ----这是MVVM、MVP和MVC之间的分流点-----

    模型:我为您找到了一个列表,viewmodel presenter,这里是json"["name":"钢琴老师","year":2001,"name":"钢琴","year":1993]"[mvm mvp]

    模型:有一些结果可用,控制器。我在实例中创建了一个字段变量,并用结果填充它。它的名字是"SearchResultsList"[MVC]

    (演示者控制器感谢模型并返回视图)[MVP MVC]

    主持人:感谢您的等待,我为您找到了一个匹配结果的列表,并以可展示的格式对其进行了安排:"2001钢琴老师","1993钢琴"。另外,请立即隐藏进度条[MVP]

    控制器:感谢等待视图,我已经询问了模型关于您的搜索查询。它说它找到了一个匹配结果的列表,并将它们存储在实例中名为"searchresultslist"的变量中。你可以从那里得到它。另外,请立即隐藏进度条[MVC]

    视图模型:搜索结果上的任何观察者都会被通知存在可显示格式如下的新列表:【2001钢琴老师】、【1993钢琴】。【MVVM】

    视图:非常感谢演示者[MVP]

    视图:感谢"控制器"[MVC](现在视图本身正在质疑:我应该如何向用户展示从模型中获得的结果?电影的制作年份应该是第一个还是最后一个…?)

    视图:哦,searchresultsilstobservable中有一个新的触发器…,很好,有一个可显示的列表,现在我只需要在列表中显示它。既然我得到了结果,我也应该隐藏进度条。[MVVM]

    如果您感兴趣,我在这里写了一系列文章,通过实现电影搜索Android应用程序来比较MVVM、MVP和MVC。


    通常,MVC用于Web开发,MVVM在WPF/Silverlight开发中最受欢迎。然而,有时Web架构可能混合了MVC和MVVM。

    例如:您可以使用knockout.js,在这种情况下,您的客户机端将有MVVM。MVC的服务器端也可以改变。在复杂的应用程序中,没有人使用纯模型。使用一个视图模型作为MVC的"模型"可能是有意义的,并且您的真实模型基本上将是这个虚拟机的一部分。这为您提供了一个额外的抽象层。


    MVVMC,或者可能是MVC+,似乎是企业和快速应用程序开发的可行方法。虽然将UI与业务逻辑和交互逻辑分开很好,但"纯"MVVM模式和大多数可用示例在单一视图上的效果最好。

    不确定您的设计,但是我的大多数应用程序都包含页面和几个(可重用)视图,因此视图模型需要在某种程度上进行交互。将页面作为控制器将完全破坏MVVM的目的,因此不使用底层逻辑的"VM-C"方法可能会导致……好。。随着应用程序的成熟,具有挑战性的构造。即使在VB-6中,我们中的大多数人也可能停止将业务逻辑编码到按钮事件中,并开始将命令"中继"到控制器,对吗?我最近看了许多关于这个主题的新兴框架;我最喜欢的显然是麦哲伦(在codeplex)方法。快乐编码!

    http://en.wikipedia.org/wiki/model_view_view model参考


    在MVVM中,控制器不会被viewModel替换,因为viewModel的功能与控制器完全不同。你仍然需要一个控制器,因为如果没有控制器,你的模型,视图模型和视图不会有太大的作用…在mvvvm中,您也有一个控制器,名称mvvvm只是有错。

    在我看来,MVVMC是正确的名字。

    如您所见,ViewModel只是MVC模式的一个补充。它将转换逻辑(例如,将对象转换为字符串)从控制器移动到视图模型。


    我曾经认为MVC和MVVM是一样的。现在,由于通量的存在,我可以区分:

    在MVC中,对于应用程序中的每个视图,都有一个模型和一个控制器,所以我将其称为视图、视图模型和视图控制器。该模式不能告诉您一个视图如何与另一个视图通信。因此,在不同的框架中有不同的实现。例如,在一些实现中,控制器之间相互通信,而在其他实现中,有另一个组件在它们之间进行中介。甚至有些实现中视图模型彼此通信,这是MVC模式的一个突破,因为视图模型只应由视图控制器访问。

    在MVVM中,每个组件都有一个视图模型。模式没有指定检查视图应该如何影响视图模型,因此通常大多数框架只在视图模型中包含控制器的功能。但是,MVVM确实告诉您,视图模型的数据应该来自模型,而模型是不知道的整个模型,或者是特定视图的自定义模型。

    为了证明差异,我们来看看通量模式。Flux模式说明应用程序中的不同视图应该如何通信。每个视图监听一个存储并使用调度程序触发操作。然后,调度器将刚才所做的操作告知所有存储,存储也会自行更新。Flux中的存储对应于MVVM中的(通用)模型。它不是任何特定视图的自定义。所以通常当人们使用react和flux时,每个react组件实际上实现了MVVM模式。当一个操作发生时,视图模型调用调度器,最后根据存储中的更改(即模型)进行更新。不能说每个组件都实现了MVC,因为在MVC中,只有控制器才能更新视图模型。因此,MVVM可以与Flux一起工作(MVVM处理视图和视图模型之间的通信,Flux处理不同视图之间的通信),而MVC不能在不破坏关键原则的情况下与Flux一起工作。


    从实际角度看,模型-视图控制器(MVC)是一种模式。但是,当MVC用作ASP.NET MVC时,与实体框架(EF)和"电动工具"结合使用时,它是一种非常强大的、部分自动化的方法,用于将数据库、表和列带到网页上,仅用于完整的CRUD操作或R(检索或读取)操作。至少在我使用MVVM的时候,视图模型与依赖于业务对象的模型交互,而这些业务对象又是"手工制作的",经过大量的努力,一个人很幸运地得到了和ef"开箱即用"一样好的模型。从实际的编程角度来看,MVC似乎是一个不错的选择,因为它提供了许多现成的实用程序,但仍然有可能添加铃声和口哨。


    作为对给出的许多响应的补充,我想从现代客户端Web或富Web应用程序的角度添加一些额外的视角。

    事实上,现在简单的网站和更大的Web应用程序通常是由许多流行的库(如bootstrap)构建的。由SteveSanderson构建的knockout为MVVM模式提供支持,该模式模拟了模式中最重要的行为之一:通过视图模型进行数据绑定。只需一点javascript,就可以实现数据和逻辑,然后使用简单的data-bindhtml属性添加到页面元素中,类似于使用引导的许多特性。同时,这两个库单独提供交互式内容;当与路由结合使用时,这种方法可以产生一种简单而强大的方法来构建单页应用程序。

    类似地,像Angular这样的现代客户端框架按照约定遵循MVC模式,但也添加了一个服务。有趣的是,它被吹捧为模型视图(model view whatever,MVW)。(请参阅关于堆栈溢出的本文。)

    此外,随着诸如Angular2等渐进式Web框架的兴起,我们看到了术语的变化,也许是一种新的体系结构模式,其中组件由视图或模板组成,并与服务交互——所有这些都可以包含在一个模块中;一系列模块构成了应用程序。


    MVC是服务器端,MVVM是Web开发中的客户端(浏览器)。

    大多数时候,浏览器中的mvvm都使用javascript。MVC有许多服务器端技术。