MVP和MVC有什么区别?


2133

当超越RAD(拖放和配置)构建用户界面的方式时,许多工具鼓励您使用三种设计模式,分别称为Model-View-ControllerModel-View-PresenterModel-View-ViewModel。我的问题包括三个部分:

  1. 这些模式解决了哪些问题?
  2. 它们有何相似之处?
  3. 它们有何不同?


2
IDK,但据说是用于原始MVC的,它原本打算用于小型机。每个按钮,标签等都有其自己的视图和控制器对象,或者至少是Bob叔叔所声称的。我认为他是在谈论Smalltalk。在YouTube上查找他的演讲很有趣。
still_dreaming_1

MVP通过将视图控制器分为视图和演示者来添加额外的间接层...
the_prole '18

2
主要区别在于,在MVC中,控制器不会将任何数据从模型传递到视图。它只是通知视图从模型本身获取数据。但是,在MVP中,视图和模型之间没有连接。演示者本身从模型中获取所需的任何数据,并将其传递给视图以进行显示。有关此内容以及所有架构模式中的android示例的更多信息,请访问:digigene.com/category/android/android-architecture
Ali Nem,

它们被称为建筑模式而不是设计模式。如果您想知道不同之处,请检查
Hasan El-Hefnawy

Answers:


1996

模型视图演示者

MVP中,Presenter包含视图的UI业务逻辑。View委托的所有调用均直接传递给Presenter。演示者也直接从视图中分离出来,并通过界面与之对话。这是为了在单元测试中模拟View。MVP的一个共同属性是必须有很多双向分配。例如,当某人单击“保存”按钮时,事件处理程序将委托给演示者的“ OnSave”方法。保存完成后,演示者将通过其界面回调视图,以便视图可以显示保存已完成。

MVP往往是在Web窗体中实现独立表示的非常自然的模式。原因是View总是首先由ASP.NET运行时创建。您可以找到有关这两种变体的更多信息

两个主要变化

被动视图:视图尽可能愚蠢,并且包含几乎为零的逻辑。演示者是与视图和模型对话的中间人。视图和模型完全相互屏蔽。模型可以引发事件,但是演示者订阅了这些事件以更新视图。在Passive View中,没有直接的数据绑定,而是View公开了Presenter用于设置数据的setter属性。所有状态都在Presenter中管理,而不是在View中管理。

  • 优点:最大的可测试性表面;视图和模型的清晰分离
  • 缺点:在自己进行所有数据绑定时,需要做更多的工作(例如,所有的setter属性)。

监督控制器:演示者处理用户手势。视图通过数据绑定直接绑定到模型。在这种情况下,演示者的工作是将模型传递给视图,以便可以绑定到视图。演示者还将包含手势的逻辑,例如按下按钮,导航等。

  • 优点:通过利用数据绑定,减少了代码量。
  • 缺点:可测试的表面较少(由于数据绑定),视图中的封装较少,因为它直接与模型对话。

模型视图控制器

MVC中,控制器负责确定响应于任何操作(包括应用程序何时加载)显示哪个视图。这与MVP不同,在MVP中,操作通过视图路由到演示者。在MVC中,视图中的每个动作都与对控制器的调用以及一个动作相关联。在网络中,每个动作都涉及对URL的调用,在该URL的另一侧有一个Controller响应。该控制器完成处理后,将返回正确的视图。该序列在应用程序的整个生命周期中都以这种方式继续:

    视图中的操作
        ->呼叫控制器
        ->控制器逻辑
        ->控制器返回视图。

关于MVC的另一大区别是,视图不直接绑定到模型。该视图只是呈现,并且是完全无状态的。在MVC的实现中,视图中的代码通常不会包含任何逻辑。这与绝对必要的MVP相反,因为如果View不委托给Presenter,它将永远不会被调用。

展示模型

另一个要看的模式是演示模型图案。在这种模式下,没有演示者。相反,视图直接绑定到演示模型。Presentation Model是专门为View设计的模型。这意味着该模型可以公开一个永远不会放在域模型上的属性,因为这将违反关注点分离。在这种情况下,表示模型绑定到域模型,并且可以订阅来自该模型的事件。然后,View订阅来自Presentation Model的事件并相应地更新自身。Presentation Model可以公开视图用于调用动作的命令。这种方法的优点是,由于PM完全封装了视图的所有行为,因此您基本上可以完全删除后面的代码。模型-视图-视图模型

MSDN上关于演示模型的文章,在WPF(前棱镜)的复合应用指南中有关于单独的演示模式的部分


27
能否请您澄清一下这句话?这与MVP不同,在MVP中,操作通过视图路由到演示者。在MVC中,视图中的每个动作都与对控制器的调用以及一个动作相关联。对我来说,这听起来像是同一件事,但是我敢肯定,您描述的是不同的东西。
Panzercrisis

16
@Panzercrisis我不确定这是否是作者的意思,但这是我想他们要说的。像这个答案一样-stackoverflow.com/a/2068/74556提到,在MVC中,控制器方法基于行为-换句话说,您可以将多个视图(但行为相同)映射到单个控制器。在MVP中,演示者耦合得更靠近视图,并且通常会导致更接近一对一的映射,即视图动作映射到其相应的演示者的方法。通常,您不会将另一个视图的操作映射到另一个演示者(从另一个视图)的方法。
达斯汀·肯德尔

2
请注意, MVC Web框架通常使用,例如Laravel,其中接收到的URL请求(可能由用户提出)由来处理,Controller而生成的HTML View发送给客户端-因此,View属于后端和用户永远无法直接访问它,如果您遇到相反的情况,则可以将其视为MVC扩展(甚至违反)。@Panzercrisis,这不同于MVP(和AndroidOS 中使用的一样),在该环境中actions route through the View to the Presenter,用户可以直接访问View
顶级大师

454

这是这些设计模式的许多变体的过度简化,但这就是我想考虑两者之间的差异的方式。

MVC

MVC

最有价值球员

在此处输入图片说明


10
这是对示意图的很好描述,显示了与演示者的API相关的任何GUI相关(视图内容)的抽象和完全隔离。一点要点:可以在只有一位发言人的情况下使用主发言人,而不是每个视图一位,但是您的图表是最干净的。IMO,MVC / MVP之间的最大区别在于,MVP试图使视图完全不显示除显示当前“视图状态”(视图数据)以外的任何内容,同时也不允许视图对模型对象有任何了解。因此,需要存在的接口才能注入该状态。

4
好照片。我使用MVP的次数很多,所以我只想提出一点。根据我的经验,主持人需要经常互相交谈。对于模型(或业务对象)也是如此。由于这些附加的“蓝线”将出现在您的MVP图片中,因此Presenter-Model关系可能会变得很纠结。因此,我倾向于保持一对一的Presenter-Model关系与一对多的关系。是的,它在模型上需要一些其他的委托方法,但是如果模型的API发生更改或需要重构,则可以减少很多麻烦。
splungebob 2014年

3
MVC示例是错误的;视图和控制器之间存在严格的1:1关系。根据定义,控制器会解释人的手势输入,以生成模型的事件,并为单个控件提供类似的视图。更简单地说,MVC仅用于单个小部件。一个小部件,一个视图,一个控件。
Samuel A. Falvo II '04

3
@ SamuelA.FalvoII并非总是如此,ASP.NET MVC中的控制器和视图之间有很多1:1:stackoverflow.com/questions/1673301/…–
StuperUser

4
@StuperUser-不知道我写的时候在想什么。当然,您是对的,回头看我写的内容,我想知道我是否还有其他我无法阐明的背景。感谢您的更正。
Samuel A. Falvo II

421

不久前,我写了一篇关于这件事的博文,并引用了托德·斯奈德(Todd Snyder)的出色文章,介绍了两者之间的区别

以下是这些模式之间的主要区别:

MVP模式

  • 视图与模型之间的联系更加松散。演示者负责将模型绑定到视图。
  • 单元测试更容易,因为与视图的交互是通过界面进行的
  • 通常情况下,与演示者的地图是一对一的。复杂的视图可能有多个演示者。

MVC模式

  • 控制器基于行为,可以在视图之间共享
  • 可以负责确定要显示哪个视图

这是我在网上找到的最好的解释。


15
我不明白,在两种情况下,要点是要完全将模型解耦时,视图中的模型如何或多或少地紧密耦合。我并不是在暗示您说错了什么,只是对您的意思感到困惑。
Bill K

18
@pst:使用MVP时,实际上是1个视图= 1个演示者。使用MVC,Controller可以管理多个视图。就是这样。使用“选项卡”模型,想象每个选项卡都具有自己的Presenter,而不是为所有选项卡都具有一个Controller。
乔恩·林贾普

4
最初有两种类型的控制器:一种是您说可以在多个视图之间共享的控制器,另一种是特定于视图的控制器,主要用于调整共享控制器的接口。
Acsor

1
@JonLimjap反正一个视图是什么意思?在iOS编程中,它是一屏式的吗?这会使iOS的控制器更像MVP而不是MVC吗?(另一方面,每个屏幕上也可以有多个iOS控制器)
huggie 2014年

2
托德的MVC图解说明与将视图和模型分离的想法完全矛盾。如果查看该图,它会显示“模型更新视图”(从模型到视图的箭头)。在哪个Universe中是一个系统,其中Model直接与View交互,即一个分离的View?
灰烬

260

这是代表通信流程的插图

在此处输入图片说明

在此处输入图片说明


43
我对MVC图有疑问。我没有得到视图去获取数据的部分,我认为控制器将把所需的数据转发给视图。
Brian Rizo

54
如果用户单击按钮,该按钮如何不与视图交互?我觉得在MVC中,用户与视图的交互比控制器更多
Jonathan

5
我知道这是一个旧答案-但是有人可以在@JonathanLeaders点上回应吗?我来自winforms背景,除非您做了一些非常独特的编码,否则当您单击UI / View时,首先要了解单击的知识。至少据我所知?
Rob P.

6
@RobP。我认为这类图表总是太复杂或太简单。另外,对于MVC应用程序,MVP图表的流程也是如此。视语言功能(数据绑定/观察者)而定,可能会有变化,但是最终的想法是将视图与应用程序的数据/逻辑分离。
卡·富比尔(LucaFülbier)'16

15
@JonathanLeaders 当人们说“ MVC”时,他们的想法实际上完全不同。创建此图表的人可能会想到经典的Web MVC,其中“用户输入”是HTTP请求,“视图返回给用户”是呈现的HTML页面。因此,从经典Web MVC应用程序的作者的角度来看,用户和视图之间的任何交互都不“存在”。
cubuspl42

170

MVP是不是一定是这样一个场景,查看负责(见Taligent公司的例如MVP)。
我发现不幸的是,人们仍然将其作为一种模式(负责视图)而不是反模式来宣讲,因为它与“这只是一个视图”(实用程序员)相矛盾。“这只是一个视图”指出向用户显示的最终视图是该应用程序的第二要务。微软的MVP模式使视图的重用变得更加困难,并且为微软的设计师鼓励不良做法提供了便利

坦率地说,我认为MVC的根本问题对于任何MVP实现都是正确的,并且差异几乎完全是语义上的。只要您遵循视图(显示数据),控制器(初始化和控制用户交互)和模型(基础数据和/或服务)之间的关注点分离,那么您就可以实现MVC的好处。如果您正在获得收益,那么谁真正在乎您的模式是MVC,MVP还是监督控制器?唯一的真实模式仍然是MVC,其余的只是它的不同风格。

考虑一下激动人心的文章,它全面列出了许多这些不同的实现。您可能会注意到,他们基本上都在做相同的事情,但略有不同。

我个人认为MVP只是在最近才重新引入,因为它可以减少在争论某些东西是否真正MVC的语义顽固派之间的争论,或者为证明Microsoft快速应用程序开发工具的合理性。在我的书中,这两个原因均不能证明其作为独立设计模式的存在。


28
我已经阅读了一些有关MVC / MVP / MVVM / etc之间差异的答案和博客。实际上,当您精疲力尽时,都是一样的。是否具有接口以及是否使用设置器(或任何其他语言功能)并不重要。看来,这些模式之间的差异源自各种框架的实现方式的差异,而不是概念问题。
迈克尔

6
我不会将MVP称为反模式,因为在后面的文章“ ..其余[包括MVP]只是[MVC] ..的不同风味”,这意味着如果MVP是反模式,那么是MVC ...这只是采用其他框架方法的一种味道。(现在,对于不同的任务,某些特定的 MVP实现可能比某些特定的 MVC实现更可取或更少...)

@Quibblsome:“我个人认为MVP只是最近才重新引入,因为它可以减少在争论某些东西是否真正是MVC的语义偏执者之间的争论。单独的设计模式。” 。它的差异足以使其与众不同。在MVP中,视图可以是满足预定义接口的任何内容(MVP中的视图是独立组件)。在MVC中,控制器是为特定视图而设计的(如果关系的顾虑可能使某人觉得值得再来一遍)。
Hibou57

6
@ Hibou57,没有什么可以阻止MVC将视图引用为接口或为几个不同的视图创建通用控制器。
Quibblesome

1
塞缪尔(Samuel)请澄清您在说什么。除非您告诉我“发明” MVC的团队历史,否则我对您的文字非常怀疑。如果您只是在谈论WinForm,那么还有其他处理方法,我创建了WinForm项目,其中控件绑定是由控制器而不是“单个控件”管理的。
Quibblesome 2014年

110

MVP:视图负责。

在大多数情况下,视图会创建其演示者。演示者将与模型进行交互并通过界面操纵视图。视图有时通常会通过某些界面与演示者进行交互。这归结为实施;您是否希望视图调用演示者上的方法,还是希望视图具有演示者监听的事件?归结为:视图了解演示者。该视图委托给演示者。

MVC:控制器负责。

控制器是根据某些事件/请求创建或访问的。控制器然后创建适当的视图,并与模型进行交互以进一步配置视图。归结为:控制器创建并管理视图;该视图是控制器的从属。该视图不了解控制器。


3
“视图不了解Controller。” 我认为您的意思是视图与模型没有直接联系?
Lotus Notes

2
视图永远都不应该知道模型中的任何一个。
Brian Leahy

4
@Brian:“在大多数情况下,视图都会创建为演示者。” 。我主要看到的是相反的情况,演示者同时启动了模型和视图。好吧,View可能也会启动Presenter,但这一点并不是最明显的地方。最重要的是在生命的后期发生。
Hibou57

2
您可能需要编辑答案以进一步解释:由于视图不了解控制器,因此如何将用户在屏幕上看到的“视觉”元素(即视图)上执行的用户操作传达给控制器...

77

在此处输入图片说明

MVC(模型视图控制器)

输入首先指向控制器,而不是视图。该输入可能来自与页面交互的用户,但也可能来自简单地在浏览器中输入特定的URL。在任何一种情况下,其Controller都与之连接以启动某些功能。控制器和视图之间存在多对一的关系。这是因为单个控制器可以根据正在执行的操作选择要渲染的不同视图。请注意从控制器到视图的单向箭头。这是因为视图不了解控制器或对该控制器没有任何参考。Controller确实会传回模型,因此在View和传递给它的预期模型之间有知识,但Controller没有提供知识。

MVP(模型视图演示者)

输入从“视图”而不是“演示者”开始。视图和关联的Presenter之间存在一对一的映射。视图包含对演示者的引用。演示者还对从视图触发的事件做出反应,因此它知道与之关联的视图。演示者根据其在模型上执行的请求操作来更新视图,但是视图不支持模型。

更多参考


但是在MVP模式上,当应用程序第一次加载时,主持人不是负责加载第一个视图吗?例如,当我们加载facebook应用程序时,主持人是否不负责加载登录页面?
毒蛇

2
在MVC中从模型到视图的链接?给定此链接,您可能需要编辑答案以说明如何使它成为“解耦”系统。提示:您可能会发现很难。另外,除非您认为读者会很乐意接受他们一生都在错误地计算,否则您可能想详细说明为什么尽管用户与屏幕上的“视觉”元素进行了交互,但操作还是首先通过MVC通过Controller处理(例如,视图),而不是处理后的抽象层。
灰烬

2
这显然是错误的……在MVC中,模型永远不会直接与视图对话,反之亦然。他们甚至不知道其他人存在。控制器是将它们粘合在一起的
粘合剂

1
我同意Ash和MegaManX。在MVC图表中,箭头应从View指向模型(或ViewModel或DTO),而不是从Model到View。因为模型不知道视图,但是视图可能知道模型。
Jboy Flaga

57

这个问题有很多答案,但是我觉得有必要将一些非常简单的答案清楚地比较两者。这是用户在MVP和MVC应用中搜索电影名称时所进行的讨论:

用户:单击单击…

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

用户:我只是点击了搜索按钮...

视图:好的,稍等片刻……。[ MVP | MVC ]

查看呼叫Presenter | Controller的视图 …)[ MVP | MVC ]

查看:嘿演示 | 控制器,一个用户刚刚单击搜索按钮,我该怎么办?[ MVP | MVC ]

主持人 | 控制器:嘿查看,是否有任何网页上的搜索字词?[ MVP | MVC ]

视图:是的,这里是…“钢琴” [ MVP | MVC ]

主持人:感谢View,…同时我正在查找Model上的搜索字词,请向他/她显示进度条[ MVP | MVC ]

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

主持人 | 管理员:嗨,模特儿,您对此搜索词有任何匹配吗?:“ piano” [ MVP | MVC ]

模特:嘿主持人 | 控制器,让我检查一下... [ MVP | MVC ]

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

( 过了一会儿 ... )

--------------这就是MVP和MVC开始分歧的地方---------------

模特:我为您找到了一个Presenter列表,在JSON中是“ [{{name”:“ Piano Teacher”,“ year”:2001},{“ name”:“ Piano”,“ year”:1993} ]” [ MVP ]

型号Controller,有一些结果可用。我已经在实例中创建了一个字段变量,并用结果填充了它。它的名称是“ searchResultsList” [ MVC ]

主持人 |控制器感谢模型并回到视图)[ MVP | MVC ]

演示者:感谢View的等待,我为您找到了匹配的结果列表,并以合适的格式排列它们:[“ Piano Teacher 2001”,“ Piano 1993”]。请在垂直列表中向用户显示。另外,请立即隐藏进度栏[ MVP ]

控制器:感谢您等待View,我已向Model询问您的搜索查询。它说已找到匹配结果的列表,并将它们存储在其实例内部的名为“ searchResultsList”的变量中。您可以从那里得到它。还请现在隐藏进度条[ MVC ]

视图:非常感谢主持人 [ MVP ]

视图:谢谢“控制器” [ MVC ](现在视图正在质疑自己:我应该如何展示从模型中获得的结果给用户?电影的制作年份是第一还是最后一年??是垂直列表还是水平列表?...)

如果您有兴趣,我已经撰写了一系列有关应用程序架构模式(MVC,MVP,MVVP,干净架构等)的文章,并附有Github回购 在这里。即使该示例是为android编写的,其基本原理也可以应用于任何媒介。


基本上,您要说的是控制器对视图逻辑进行微管理?因此,它通过显示发生了什么以及如何处理视图而使视图变得笨拙。
Radu

@Radu,不,它不是微观管理,这是演示者通过使视图变为被动或愚蠢而执行的操作
Ali Nem,

4
在适当的MVC中,视图调用控制器上的功能,并侦听模型中的数据更改。该视图未从控制器获取数据,并且控制器不应告知该视图显示(例如)加载指示器。适当的MVC允许您用根本不同的视图部分替换视图部分。视图部分包含视图逻辑,其中包括加载指示符。该视图调用指令(在控制器中),控制器修改模型中的数据,模型将其数据更改通知其侦听器,这种侦听器就是视图。
汤米·安德森

35
  • MVP =模型视图呈现器
  • MVC =模型-视图-控制器

    1. 两种演示模式。它们将模型(认为域对象),屏幕/网页(视图)以及用户界面的行为(演示者/控制器)之间的依赖关系分开。
    2. 它们在概念上非常相似,人们根据喜好不同地初始化Presenter / Controller。
    3. 关于差异的一篇很棒的文章在这里。最值得注意的是,MVC模式具有更新视图的模型。

2
模型更新。这仍然是一个解耦的系统吗?
灰烬

34

模型视图控制器

MVC是软件应用程序体系结构的一种模式。它将应用程序逻辑分为三个独立的部分,从而提高了模块性,并简化了协作和重用。它还使应用程序更加灵活并欢迎迭代,并将应用程序分为以下组件:

  • 楷模处理数据和业务逻辑的
  • 控制器用于处理用户界面和应用程序的
  • 用于处理图形用户界面对象和演示的视图

为了更清楚一点,让我们想象一个简单的购物清单应用程序。我们只需要列出本周需要购买的每件商品的名称,数量和价格。下面我们将描述如何使用MVC实现某些功能。

在此处输入图片说明

模型视图演示者

  • 模型是将在视图(用户界面)显示的数据。
  • 视图是一个界面,用于显示数据(模型)并将用户命令(事件)路由到Presenter以对该数据进行操作。该视图通常引用其Presenter。
  • 演示是“中间人”(由控制器在MVC饰演),并具有两个,视图和模型引用。请注意,“模型”一词具有误导性。应当是检索或操纵Model的业务逻辑。例如:如果您有一个在数据库表中存储User的数据库,并且View要显示用户列表,则Presenter将引用您的数据库业务逻辑(例如DAO),Presenter将在该数据库中查询列表的用户。

如果您想查看具有简单实现的示例,请查看 GitHub帖子

从数据库查询和显示用户列表的具体工作流程可以像这样工作: 在此处输入图片说明

MVCMVP模式之间有什么区别

MVC模式

  • 控制器基于行为,可以在视图之间共享

  • 可以负责确定要显示的视图(前端控制器模式)

MVP模式

  • 视图与模型之间的联系更加松散。演示者负责将模型绑定到视图。

  • 单元测试更容易,因为与视图的交互是通过界面进行的

  • 通常情况下,与演示者的地图是一对一的。复杂的视图可能有多个演示者。


2
不,在mvc中,视图和模型之间没有直接联系。你的图是错误的。
Özgür的

33

还值得记住的是,MVP的类型也不同。Fowler将模式分为两种-被动视图和监督控制器。

使用被动视图时,视图通常会实现细粒度的界面,其属性或多或少直接映射到底层UI小部件。例如,您可能有一个具有名称和地址之类的ICustomerView的属性。

您的实现可能看起来像这样:

public class CustomerView : ICustomerView
{
    public string Name
    { 
        get { return txtName.Text; }
        set { txtName.Text = value; }
    }
}

Presenter类将与模型对话,并将其“映射”到视图。这种方法称为“被动视图”。好处是视图易于测试,并且在UI平台(Web,Windows / XAML等)之间移动也更容易。缺点是您不能利用数据绑定之类的东西(在WPFSilverlight等框架中,它确实很强大)。

MVP的第二种形式是监督控制器。在这种情况下,您的视图可能具有一个名为Customer的属性,然后再次将其数据绑定到UI小部件。您不必考虑对视图进行同步和微管理,并且监督控制器可以在需要时介入并提供帮助,例如,使用强制的交互逻辑。

MVP的第三个“风味”(或者有人可能将其称为单独的模式)是Presentation Model(或有时称为Model-View-ViewModel)。与MVP相比,您将M和P“合并”到一个类别中。您的UI对象是数据绑定到的客户对象,但是您还具有其他特定于UI的字段,例如“ IsButtonEnabled”或“ IsReadOnly”等。

我认为,我发现有关UI体系结构的最佳资源是Jeremy Miller在“构建自己的CAB系列目录”中撰写的一系列博客文章。他介绍了MVP的所有方面,并展示了实现它们的C#代码。

YouCard重新访问的时候,我还在 Silverlight的上下文中写了有关Model-View-ViewModel模式的博客:重新实现了ViewModel模式


25

它们各自解决不同的问题,甚至可以组合在一起形成如下所示的内容

组合模式

这里还有MVC,MVP和MVVM的完整比较


1
您可以回答问题,而不是使事情复杂化。这就是为什么我们大多数人都在这里。搜索了mvp和mvc之间的比较,并在此处重定向,您正在谈论的是那些与OP无关的体系结构的协调性。
Farid

18

这两个框架的目的都是分开关注,例如,与数据源(模型)的交互,应用程序逻辑(或将这些数据转换为有用的信息)(控制器/演示器)和显示代码(视图)。在某些情况下,该模型还可以用于将数据源转换为更高级别的抽象。MVC Storefront项目就是一个很好的例子。

有一个讨论,这里就VS MVP MVC之间的差异。

所做出的区别是,在MVC应用程序中,传统上具有视图,并且控制器与模型交互,但彼此不交互。

MVP设计使Presenter访问模型并与视图交互。

话虽如此,ASP.NET MVC通过这些定义是一个MVP框架,因为控制器访问模型以填充视图,而该视图本来是没有逻辑的(仅显示控制器提供的变量)。

要了解MVP与ASP.NET MVC的区别,请查看Scott Hanselman的MIX演示


7
MVC和MVP是模式,而不是框架。如果您真的认为,该主题是关于.NET框架的,则就像听到“互联网”并认为它是关于IE一样。
tereško

可以肯定的是,这个问题与2008年首次提出时相比已经有了很大的发展。此外,回头看一下我的答案(那是4年前,所以我的背景比您还多),我会说我一般然后以.NET MVC为例。
马特·米切尔

13

两者都是试图将表示和业务逻辑分离,将业务逻辑与UI方面分离的模式

在架构上,MVP是基于页面控制器的方法,而MVC是基于前端控制器的方法。这意味着在MVP标准Web表单页面中,生命周期只是通过从后面的代码中提取业务逻辑来增强。换句话说,page是服务http请求的请求。换句话说,MVP IMHO是Web表单进化类型的增强功能。另一方面,MVC完全改变了游戏,因为在页面加载之前,请求类被控制器类拦截,在那里执行业务逻辑,然后在控制器处理刚转储到页面的数据(“视图”)的最终结果中从某种意义上说,MVC(至少对我而言)对路由引擎增强的MVP的Supervising Controller风格很有帮助

他们俩都支持TDD,并且有缺点和缺点。

如何选择其中一个恕我直言的决定应基于一个人在ASP NET Web表单类型的Web开发上投入了多少时间。如果有人认为自己擅长于Web表单,我建议MVP。如果人们对页面生命周期之类的事情不太满意,那么MVC可能是解决问题的一种方法。

这是另一个博客文章链接,提供有关此主题的更多详细信息

http://blog.vuscode.com/malovicn/archive/2007/12/18/model-view-presenter-mvp-vs-model-view-controller-mvc.aspx


9

我曾经使用过MVP和MVC,尽管我们(作为开发人员)倾向于关注两种模式的技术差异,但恕我直言,MHO中MVP的意义与易用性息息相关。

如果我正在一个已经具有Web表单开发风格的良好背景的团队中工作,那么介绍MVP比MVC要容易得多。我想说,在这种情况下,MVP是一个快速的胜利。

我的经验告诉我,将团队从Web表单迁移到MVP,然后从MVP迁移到MVC相对容易。从Web表单迁移到MVC更加困难。

我在这里留下指向我的一个朋友发表的有关MVP和MVC的系列文章的链接。

http://www.qsoft.be/post/Building-the-MVP-StoreFront-Gutthrie-style.aspx


8

在MVP中,视图从演示者中提取数据,演示者从模型中提取数据并对其进行准备/归一化;而在MVC中,控制器通过推入视图从模型中进行数据设置。

在MVP中,您可以具有一个与多种类型的演示者一起使用的视图,以及一个与不同的多种视图一起使用的演示者。

MVP通常使用某种绑定框架,例如Microsoft WPF绑定框架或用于HTML5和Java的各种绑定框架。

在这些框架中,UI / HTML5 / XAML知道每个UI元素显示的演示者的属性,因此,当您将视图绑定到演示者时,视图将查找属性,并且知道如何从它们中绘制数据以及如何在用户更改UI中的值时进行设置。

因此,例如,如果模型是一辆汽车,那么演示者就是某种汽车演示者,将汽车属性(年份,制造商,座位等)暴露给视图。该视图知道称为“汽车制造商”的文本字段需要显示Presenter Maker属性。

然后,您可以将许多不同类型的演示者绑定到视图,所有演示者都必须具有Maker属性-它可以是飞机,火车或其他任何东西,该视图无关紧要。只要实现了约定的界面,该视图就会从演示者那里获取数据-无论哪种方式。

这个绑定框架,如果将其剥离,实际上是控制器:-)

因此,您可以将MVP视为MVC的演进。

MVC很棒,但是问题在于通常每个视图都有它的控制器。控制器A知道如何设置视图A的字段。如果现在,您希望视图A显示模型B的数据,则需要控制器A知道模型B,或者需要控制器A接收带有接口的对象-就像仅MVP不带绑定,否则您需要在Controller B中重写UI设置代码。

结论-MVP和MVC都是UI模式的分离,但MVP通常使用下面的MVC绑定框架。THUS MVP的体系结构级别高于MVC,并且其包装模式高于MVC。


6

我的简短观点是:MVP适用于大规模,而MVC适用于小规模。使用MVC,我有时会感觉到V和C可能被视为单个不可分割组件的两个侧面,而是直接绑定到M,而当减小到更小的比例时(如UI控件和基本小部件),不可避免地会遇到这一点。在这种粒度级别上,MVP毫无意义。相反,当规模扩大时,正确的接口就变得更加重要,明确分配职责也是如此,这就是MVP。

另一方面,当平台特性有利于组件之间的某种关系时,例如在Web上,实现MVC似乎比MVP更容易,这种经验法则的权重可能很小。


4

我认为Erwin Vandervalk(及其附带的文章)提供的这张图像是MVC,MVP和MVVM及其相似之处和差异的最好解释。该文章未出现在搜索引擎结果中的“ MVC,MVP和MVVM”查询中,因为该文章的标题不包含单词“ MVC”和“ MVP”。但我认为这是最好的解释。

该图解释了MVC,MVP和MVVM-Erwin Vandervalk

本文还与Bob Martin叔叔在他的一次演讲中所说的相吻合:MVC最初是为小型UI组件而不是为系统体系结构设计的)


3

MVC有很多版本,此答案与Smalltalk中的原始MVC有关。简而言之,它是 MVC vs MVP的图像

这篇演讲droidcon NYC 2017-使用Architecture Components进行的干净应用程序设计澄清了它

在此处输入图片说明 在此处输入图片说明


6
在MVC中,永远不会直接从视图中调用模型
rodi 2015年

5
这是一个不正确的答案。不要被误导。正如@rodi所写,视图和模型之间没有交互。
肖恩·梅汉

MVC图像不准确或充其量是误导性的,请不要对此答案给予任何关注。
周杰伦

2
@ Jay1b您认为哪种MVC是“正确的”?这个答案是关于原始的MVC。还有许多其他MVC(例如iOS中的)已更改为适应该平台,例如UIKit
onmyway133

箭头是什么意思?
官员

3

这种从Bob大叔不错的视频,他简要介绍了MVCMVP底。

IMO,MVP是MVC的改进版本,您基本上可以将要显示的内容(数据)与要显示的内容(视图)分开。演示者包括您的UI的业务逻辑,隐式强加了应显示的数据,并为您提供了一个哑视图模型列表。而且,当需要显示数据时,您只需将视图(可能包括相同的ID)插入适配器,并使用引入最少代码(仅使用setter)的那些视图模型来设置相关视图字段。它的主要好处是您可以针对许多/各种视图(例如,在水平列表或垂直列表中显示项目)测试UI业务逻辑。

在MVC中,我们通过接口(边界)进行对话以粘合不同的层。控制器是我们架构的一个插件,但是它并没有施加任何限制。从这个意义上讲,MVP是一种MVC,其概念是可通过适配器将视图插入控制器。

我希望这会有所帮助。


2
Bob叔叔的要点:最初是由Trygve Reenskaug发明的,MVC是为每个小部件而不是整个窗体使用的。
罗勒·布尔克

2

您忘记了动作域响应器ADR)。

如上图所示,MVC中的模型视图之间存在直接关系/链接。在Controller上执行一个动作,该Controller将在Model上执行一个动作。在这一行动模式将触发反应视图。该视图的时候总是更新型号的状态发生改变。

有些人忘记了MVC 是在70年代后期创建的,而Web只在80英寸/ 90年代初创建的。MVC最初不是为Web创建的,而是为桌面应用程序创建的,而Controller是,模型和视图将并存。

因为我们使用的Web框架(例如:。Laravel)仍然使用相同的命名约定(model-view-controller),所以我们倾向于认为它必须是MVC,但实际上是其他东西。

相反,请查看Action-Domain-Responder。在ADR中,控制器获得一个Action,它将在Model / Domain中执行操作。到目前为止,都一样。不同之处在于,它随后收集了该操作的响应/数据,并将其传递给Responder例如:)view()进行渲染。当在同一组件上请求执行新操作时,将再次调用Controller,然后循环重复进行。在ADR中,模型/域与视图(响应者的响应)之间没有联系

注意: Wikipedia指出“ 但是,每个ADR操作均由单独的类或闭包表示。 ”。这是完全正确。多个动作可以在同一Controller中,并且模式仍然相同。


2

最简单的答案是视图如何与模型交互。在MVP中,视图由演示者更新,该演示者充当视图和模型之间的中介。演示者从视图中获取输入,该视图从模型中检索数据,然后执行所需的任何业务逻辑,然后更新视图。在MVC中,模型直接更新视图,而不是通过控制器返回。


我已经投票了,因为afaik模型对MVC中的视图一无所知,并且在编写时无法直接更新它。
问题人员

1
看看Wikipedia上的MVC,这就是它的工作原理。
Clive Jefferies

1
不管读者是否喜欢,通过谷歌搜索可以找到大量资源,这些资源表明在MVC中视图订阅了模型的更新。在某些情况下甚至可能控制器,因此调用这些更新。如果您不喜欢它,那就去抱怨那些文章,或者引用您认为是唯一合法来源的“圣经”,而不是拒绝回答那些只是在这里传递其他可用信息的答案!
underscore_d

1
措词肯定可以改进,但是确实视图支持MVC中的模型更改。该模型不需要知道MVC中的视图。
吞噬了极乐

谢谢..这对我有很大帮助
Dvyn Resh

1
  • 在MVC中,View具有UI部分,控制器是视图与模型之间的中介,而模型则包含业务逻辑。
  • 在MVP中,View包含演示者的UI和实现,因为在这里,演示者只是一个接口,模型是相同的,即包含业务逻辑。

-1

最有价值球员

MVP代表模型-视图呈现器。这是2007年初的一张照片,Microsoft引入了Smart Client Windows应用程序。

演示者在MVP中充当监督角色,该MVP绑定了View事件和模型中的业务逻辑。

视图事件绑定将通过视图界面在Presenter中实现。

该视图是用户输入的发起者,然后将事件委托给Presenter,presenter处理事件绑定并从模型获取数据。

优点: 视图仅具有UI,没有任何逻辑高可测试性

缺点: 实现事件绑定时有点复杂并且工作更多

MVC

MVC代表模型-视图-控制器。Controller负责创建模型并使用绑定模型渲染视图。

控制器是发起者,它决定渲染哪个视图。

优点: 强调单一责任原则高水平的可测试性

缺点: 如果尝试在同一控制器中呈现多个视图,则有时对于Controllers来说工作量过多。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.