ChatGPT解决这个技术问题 Extra ChatGPT

什么是 MVP 和 MVC,有什么区别?

想要改进这篇文章?提供这个问题的详细答案,包括引文和解释为什么你的答案是正确的。没有足够细节的答案可能会被编辑或删除。

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

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

IDK,但据说对于原始的 MVC,它是用于小型的。每个按钮、标签等都有自己的视图和控制器对象,或者至少 Bob 大叔声称是这样。我认为他在谈论 Smalltalk。在 YouTube 上查看他的演讲,它们很有趣。
MVP 通过将 View-Controller 拆分为 View 和 Presenter 来添加额外的间接层......
主要区别在于,在 MVC 中,控制器不会将任何数据从模型传递到视图。它只是通知视图从模型本身获取数据。然而,在 MVP 中,View 和 Model 之间没有任何联系。 Presenter 本身从 Model 中获取所需的任何数据并将其传递给 View 以显示。更多内容以及所有架构模式中的 android 示例都在这里:digigene.com/category/android/android-architecture
它们被称为架构模式而不是设计模式。如果您想知道区别,请检查 this

1
14 revs, 12 users 51%

模型-视图-演示者

在 MVP 中,Presenter 包含 View 的 UI 业务逻辑。 View 委托的所有调用都直接发送给 Presenter。 Presenter 也直接与 View 解耦,并通过接口与其对话。这是为了允许在单元测试中模拟视图。 MVP 的一个共同属性是必须有大量的双向调度。例如,当有人单击“保存”按钮时,事件处理程序将委托给 Presenter 的“OnSave”方法。保存完成后,Presenter 将通过其接口回调 View,以便 View 可以显示保存已完成。

MVP 往往是在 WebForms 中实现分离表示的一种非常自然的模式。原因是视图总是首先由 ASP.NET 运行时创建。您可以find out more about both variants

两个主要变体

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

Pro:最大的可测试性表面;视图和模型的清晰分离

缺点:当您自己进行所有数据绑定时,需要做更多工作(例如所有 setter 属性)。

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

优点:通过利用数据绑定减少了代码量。

缺点:可测试的表面较少(因为数据绑定),并且视图中的封装较少,因为它直接与模型对话。

模型-视图-控制器

在 MVC 中,Controller 负责确定显示哪个 View 以响应任何操作,包括应用程序加载的时间。这与 MVP 不同,MVP 中的操作通过 View 路由到 Presenter。在 MVC 中,视图中的每个操作都与对控制器的调用以及操作相关联。在 Web 中,每个操作都涉及对 URL 的调用,在该 URL 的另一端有一个控制器进行响应。一旦该控制器完成其处理,它将返回正确的视图。该序列在应用程序的整个生命周期中以这种方式继续:

Action in the View
        -> Call to Controller
        -> Controller Logic
        -> Controller returns the View.

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

演示模型

另一种模式是 Presentation Model 模式。在此模式中,没有 Presenter。相反,视图直接绑定到表示模型。演示模型是专门为视图制作的模型。这意味着该模型可以公开永远不会放在域模型上的属性,因为这将违反关注点分离。在这种情况下,Presentation Model 绑定到域模型并可能订阅来自该模型的事件。然后 View 订阅来自 Presentation Model 的事件并相应地更新自己。演示模型可以公开视图用于调用操作的命令。这种方法的优点是您可以从根本上完全删除代码隐藏,因为 PM 完全封装了视图的所有行为。此模式非常适合在 WPF 应用程序中使用,也称为 Model-View-ViewModel

Composite Application Guidance for WPF(前 Prism)中有一个 MSDN article about the Presentation Model 和一个关于 Separated Presentation Patterns 的部分


你能澄清一下这句话吗?这与 MVP 不同,MVP 中的操作通过 View 路由到 Presenter。在 MVC 中,视图中的每个操作都与对控制器的调用以及操作相关联。对我来说,这听起来像是同一件事,但我敢肯定你描述的是不同的东西。
@Panzercrisis 我不确定这是否是作者的意思,但这就是我认为他们想说的。像这个答案 - stackoverflow.com/a/2068/74556 提到,在 MVC 中,控制器方法基于行为 - 换句话说,您可以将多个视图(但行为相同)映射到单个控制器。在MVP 中,presenter 与视图耦合得更近,通常会产生更接近一对一的映射,即视图动作映射到其对应的presenter 的方法。您通常不会将另一个视图的操作映射到另一个演示者(来自另一个视图)的方法。
请注意 MVC 经常被 Laravel 等网络框架使用,其中接收到的 URL 请求(可能由用户发出)由 Controller 处理,而 HTML 由 {4 } 被发送到客户端——因此,Viewbackend 的一部分,用户永远无法直接访问它,如果您遇到任何相反的情况,则将其视为 MVC-延期(甚至违反)。 @Panzercrisis,这与 actions route through the View to the Presenter 和用户可以直接访问 ViewMVP(就像在 Android 操作系统中使用的那样)不同。
作者在谈到 MVC 时所描述的不是原始的 Smalltalk MVC(其流程是三角形的),而是控制器使用模型呈现视图并将其返回给用户的“Web MVC”。我认为这是值得注意的,因为这会造成很多混乱。
P
Phyxx

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

MVC

https://i.stack.imgur.com/X3CAF.png

MVP

https://i.stack.imgur.com/Pa0iB.png


这是对原理图的一个很好的描述,展示了任何与 GUI 相关(查看内容)与演示者 API 的抽象和完全隔离。一个小问题:可以在只有一个演示者的情况下使用主演示者,而不是每个视图一个,但您的图表是最干净的。 IMO,MVC/MVP 之间的最大区别在于,MVP 试图保持视图除了显示当前的“视图状态”(视图数据)之外完全没有任何内容,同时也不允许视图了解模型对象。因此,需要存在接口才能注入该状态。
好照片。我经常使用MVP,所以我想说一点。根据我的经验,演示者需要经常互相交谈。模型(或业务对象)也是如此。由于这些额外的“蓝线”通信会出现在您的 MVP 图片中,Presenter-Model 关系可能会变得非常复杂。因此,我倾向于保持一对一的 Presenter-Model 关系与一对多的关系。是的,它需要在模型上添加一些额外的委托方法,但是如果模型的 API 发生更改或需要重构,它会减少很多麻烦。
MVC 示例是错误的;视图和控制器之间存在严格的 1:1 关系。根据定义,控制器解释人类手势输入以产生模型事件和单个控件的类似视图。更简单地说,MVC 旨在仅用于单个小部件。一个小部件,一个视图,一个控件。
@SamuelA.FalvoII 并非总是如此,在 ASP.NET MVC 中的控制器和视图之间存在 1:Many:stackoverflow.com/questions/1673301/…
@StuperUser——不知道我写这篇文章时在想什么。你是对的,当然,回顾我写的东西,我不得不怀疑我是否还有其他一些我没有表达清楚的背景。感谢您的指正。
P
Peter Mortensen

不久前我在博客上引用了 Todd Snyder's excellent post on the difference between the two

以下是模式之间的主要区别: MVP 模式视图与模型的耦合更加松散。演示者负责将模型绑定到视图。更容易进行单元测试,因为与视图的交互是通过一个界面来进行的。通常视图到演示者的映射是一对一的。复杂视图可能有多个演示者。 MVC Pattern Controller 是基于行为的,可以跨视图共享 可以负责决定显示哪个视图

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


我不明白如何在视图中或多或少地与模型紧密耦合,而在这两种情况下,重点是完全解耦它们。我并不是在暗示你说错了什么——只是对你的意思感到困惑。
@pst:对于 MVP,它实际上是 1 View = 1 Presenter。使用 MVC,Controller 可以管理多个视图。就是这样,真的。使用“选项卡”模型,想象每个选项卡都有自己的 Presenter,而不是所有选项卡都有一个控制器。
最初有两种类型的控制器:一种是您所说的跨多个视图共享的控制器,另一种是特定于视图的控制器,主要用于调整共享控制器的接口。
@JonLimjap 无论如何,一个视图是什么意思?在 iOS 编程的上下文中,它是一屏的吗?这是否使 iOS 的控制器更像 MVP 而不是 MVC? (另一方面,每个屏幕也可以有多个 iOS 控制器)
好吧,Todd 对 MVC 的图解说明与解耦视图和模型的想法完全矛盾。如果您查看图表,它会显示模型更新视图(从模型到视图的箭头)。在哪个宇宙中是一个系统,模型直接与视图交互,一个解耦的???
A
Ashraf Bashir

这是代表通信流程的插图

https://i.stack.imgur.com/t2kzD.png


我有一个关于 MVC 图的问题。我没有得到视图出去获取数据的部分。我认为控制器会转发到带有所需数据的视图。
如果用户单击一个按钮,那怎么不与视图交互?我觉得在 MVC 中,用户与视图的交互多于控制器
我知道这是一个旧答案 - 但有人可以回应@JonathanLeaders 的观点吗?我来自 winforms 背景,除非您进行了一些非常独特的编码,当您单击 UI/View 时,您会先了解该点击。至少,据我所知?
@RobP。我认为这类图表总是要么太复杂,要么太简单。 Imo MVP 图表的流程也适用于 MVC 应用程序。取决于语言特性(数据绑定/观察者),可能会有变化,但最终的想法是将视图与应用程序的数据/逻辑分离。
@JonathanLeaders 当人们说“MVC”时,他们的想法真的不同。创建此图表的人可能想到了经典的 Web MVC,其中“用户输入”是 HTTP 请求,“返回给用户的视图”是呈现的 HTML 页面。因此,从经典 Web MVC 应用程序的作者的角度来看,用户和视图之间的任何交互都是“不存在的”。
Q
Quibblesome

MVP 不一定是 View 负责的场景(例如,参见 Taligent 的 MVP)。不幸的是,人们仍然将其作为一种模式(负责视图)而不是反模式来宣传,因为它与“这只是一个视图”(实用程序员)相矛盾。 “这只是一个视图”表明向用户显示的最终视图是应用程序的次要关注点。 Microsoft 的 MVP 模式使 Views 的重用变得更加困难,并且方便地为 Microsoft 的设计人员提供了鼓励不良做法的借口。

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

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

我个人认为 MVP 只是最近才作为一个吸引人的术语重新引入,以减少语义偏执者之间争论某事是否真正 MVC 或证明微软快速应用程序开发工具的合理性。在我的书中,这些原因都不能证明它作为一种单独的设计模式存在是合理的。


我已经阅读了几个关于 MVC/MVP/MVVM/etc' 之间差异的答案和博客。实际上,当你做生意时,一切都是一样的。是否有接口以及是否使用 setter(或任何其他语言功能)并不重要。这些模式之间的差异似乎源于各种框架实现的差异,而不是概念问题。
我不会将 MVP 称为反模式,因为稍后在帖子中“..其余 [包括 MVP] 只是 [MVC] 的不同风格..”,这意味着如果 MVP 是反模式,那么是 MVC ......它只是不同框架方法的一种风格。 (现在,对于不同的任务,某些特定的 MVP 实现可能比某些特定的 MVC 实现更可取……)
@Quibblsome:“我个人认为 MVP 只是最近才作为一个吸引人的术语重新引入,以减少语义偏执者之间争论某事物是否真正 MVC 的争论 [...] 在我的书中,这些原因都不能证明它的存在是合理的单独的设计模式。” .它的差异足以使其与众不同。在 MVP 中,视图可以是任何满足预定义接口的东西(MVP 中的视图是一个独立的组件)。在 MVC 中,控制器是为特定视图制作的(如果关系的属性可能会让某人觉得这值得另一个术语)。
Hibou57,没有什么可以阻止 MVC 将视图作为接口引用或为多个不同的视图创建通用控制器。
塞缪尔请澄清你在说什么。除非你告诉我“发明”MVC 的团队的历史,否则我对你的文字非常怀疑。如果您只是在谈论 WinForm,那么还有其他处理方式,我创建了 WinForm 项目,其中控件绑定由控制器管理,而不是“单个控件”。
C
Community

MVP:视图负责。

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

MVC:控制器负责。

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


“视图不知道控制器。”我认为您的意思是视图与模型没有直接联系?
view 永远不应该知道模型中的任何一个。
@Brian:“在大多数情况下,视图创建了它的演示者。” .我大多看到相反的情况,Presenter 同时启动了模型和视图。好吧,View 也可能会启动 Presenter,但这并不是最有特色的。最重要的事情发生在生命的后期。
您可能需要编辑您的答案以进一步解释:由于视图不了解控制器,用户操作如何在用户在屏幕上看到的“视觉”元素(即视图)上执行,如何与控制器通信...
A
AVI

https://i.stack.imgur.com/A7cSy.jpg

MVC(模型视图控制器)

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

MVP(模型视图展示器)

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

更多Reference


但是在 MVP 模式中,当应用程序第一次加载时,不是演示者负责加载第一个视图吗?例如,当我们加载 facebook 应用程序时,不是演示者负责加载登录页面吗?
在 MVC 中从模型到视图的链接?鉴于此链接,您可能想要编辑您的答案以解释这如何使其成为“解耦”系统。提示:你可能会觉得很难。此外,除非您认为读者会欣然接受他们一生都在计算错误,否则您可能需要详细说明为什么尽管用户与屏幕上的“视觉”元素(即视图),而不是一些位于处理背后的抽象层。
这显然是错误的......在 MVC 中,模型从不直接与视图对话,反之亦然。他们甚至不知道其他人的存在。控制器是将它们粘合在一起的粘合剂
我同意 Ash 和 MegaManX。在MVC图中,箭头应该是从View指向Model(或ViewModel,或DTO),而不是从Model指向View;因为模型不知道视图,但视图可能知道模型。
实际上,我认为基于原始 SmallTalk 三角形 MVC,模型视图链接是正确的: commons.wikimedia.org/wiki/File:MVC-Process.svg#/media/… 。我看到的问题是控制器的输入及其链接视图。通常用户与视图交互,所以视图应该链接到控制器。
R
Ray Jasson

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

用户:点击点击...

观点:那是谁? [MVP|MVC]

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

视图:好的,等一下……。 [MVP|MVC]

(视图调用 Presenter|Controller ...) [MVP|MVC]

视图:嗨 Presenter|Controller,一个用户刚刚点击了搜索按钮,我该怎么办? [MVP|MVC]

Presenter|Controller:嗨,View,那个页面上有搜索词吗? [MVP|MVC]

观点:是的,……在这里……“钢琴” [MVP|MVC]

Presenter|Controller:谢谢View,...同时我正在查找Model上的搜索词,请给他/她显示一个进度条[MVP|MVC]

(Presenter|Controller 正在调用模型……) [MVP|MVC]

演示者|控制器:嘿,模型,你有这个搜索词匹配吗?:“钢琴” [MVP|MVC]

模型:嘿 Presenter|Controller,让我检查一下…… [MVP|MVC]

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

( 过了一会儿 ... )

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

模特:我给你找到了一个列表,Presenter,这里是 JSON “[{"name":"Piano Teacher","year":2001},{"name":"Piano","year":1993} ]” [MVP]

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

(Presenter|Controller 感谢 Model 并返回 View)[MVP|MVC]

主持人:感谢您的等待查看,我为您找到了匹配结果列表,并将它们排列成一个像样的格式:[“钢琴老师2001”,“钢琴1993”]。请在垂直列表中显示给用户。也请现在隐藏进度条[MVP]

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

观点:非常感谢Presenter [MVP]

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

如果您有兴趣,我一直在撰写一系列文章,涉及应用程序架构模式(MVC、MVP、MVVP、干净架构……),并附有 Github 存储库 here。即使该示例是为 android 编写的,其基本原理也可以应用于任何媒体。


基本上你想说的是控制器微观管理视图逻辑?所以它通过呈现发生了什么以及视图如何使视图变得更笨?
@Radu,不,它不会进行微观管理,这就是演示者通过使视图被动或愚蠢所做的事情
在适当的 MVC 中,视图调用控制器上的功能,并监听模型中的数据变化。视图不从控制器获取数据,控制器不应该告诉视图显示,例如,加载指示器。适当的 MVC 允许您用完全不同的视图部分替换视图部分。视图部分包含视图逻辑,其中包括加载指示器。视图调用指令(在控制器中),控制器修改模型中的数据,模型通知其侦听器对其数据的更改,其中一个侦听器就是视图。
R
Rahul

模型-视图-控制器

MVC 是一种软件应用程序架构的模式。它将应用程序逻辑分成三个独立的部分,促进模块化以及易于协作和重用。它还使应用程序更加灵活和欢迎迭代。它将应用程序分为以下组件:

处理数据和业务逻辑的模型

用于处理用户界面和应用程序的控制器

用于处理图形用户界面对象和表示的视图

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

https://i.stack.imgur.com/xjBSZ.png

模型-视图-演示者

模型是将显示在视图(用户界面)中的数据。

视图是一个界面,它显示数据(模型)并将用户命令(事件)路由到 Presenter 以对该数据进行操作。视图通常具有对其 Presenter 的引用。

Presenter 是“中间人”(由 MVC 中的控制器扮演),并且对视图和模型都有引用。请注意,“模型”一词具有误导性。它应该是检索或操作模型的业务逻辑。例如:如果您有一个数据库将 User 存储在数据库表中,并且您的 View 想要显示用户列表,那么 Presenter 将引用您的数据库业务逻辑(如 DAO),Presenter 将从那里查询列表的用户。

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

https://i.stack.imgur.com/QwKUW.png

MVC 和 MVP 模式有什么区别?

MVC 模式

控制器基于行为,可以跨视图共享

可以负责确定显示哪个视图(前端控制器模式)

MVP模式

视图与模型的耦合更松散。演示者负责将模型绑定到视图。

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

通常以一对一的方式查看演示者地图。复杂视图可能有多个演示者。


m
multitask landscape

MVP = 模型-视图-演示者

MVC = Model-View-Controller 两种表示模式。它们分离了模型(想想域对象)、屏幕/网页(视图)以及 UI 应该如何表现(Presenter/Controller)之间的依赖关系。它们在概念上非常相似,人们以不同方式初始化 Presenter/Controller取决于口味。关于差异的精彩文章在这里。最值得注意的是 MVC 模式让模型更新视图。

两种演示模式。它们将模型(想想域对象)、屏幕/网页(视图)以及 UI 的行为方式(演示者/控制器)之间的依赖关系分开

它们在概念上非常相似,人们根据口味对 Presenter/Controller 进行不同的初始化。

关于差异的精彩文章在这里。最值得注意的是 MVC 模式让模型更新视图。


模型更新视图。这仍然是一个解耦的系统?
P
Peter Mortensen

另外值得记住的是,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 的第二种风格是监督控制器。在这种情况下,您的 View 可能有一个名为 Customer 的属性,然后再次将其数据绑定到 UI 小部件。您不必考虑同步和微观管理视图,监督控制器可以在需要时介入并提供帮助,例如复杂的交互逻辑。

MVP 的第三种“风格”(或者有人可能称其为单独的模式)是 Presentation Model(或有时称为 Model-View-ViewModel)。与 MVP 相比,您将 M 和 P “合并”为一个类。您有您的 UI 小部件数据绑定到的客户对象,但您也有额外的 UI 特定字段,如“IsButtonEnabled”或“IsReadOnly”等。

我认为我发现的有关 UI 架构的最佳资源是 Jeremy Miller 在 The Build Your Own CAB Series Table of Contents 上完成的一系列博客文章。他涵盖了 MVP 的所有风格,并展示了 C# 代码来实现它们。

我还在 YouCard Re-visited: Implementing the ViewModel pattern 上发表了有关 Silverlight 上下文中模型-视图-视图模型模式的博客。


M
Matt Mitchell

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

有一个关于 MVC 与 MVP 之间差异的讨论 here

区别在于,在 MVC 应用程序中,视图和控制器传统上与模型交互,但彼此之间不交互。

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

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

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


MVC 和 MVP 是模式,而不是框架。如果你真的认为那个话题是关于 .NET 框架的,那么就像听到“互联网”并认为它是关于 IE 的一样。
很确定这个问题从 2008 年第一次被问到时已经有了很大的发展。此外,回顾我的回答(这是 4 年前,所以我没有比你更多的背景信息)我会说我一般开始并且然后使用 .NET MVC 作为具体示例。
N
Nikola Malovic

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

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

它们都启用了 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


P
Pedro Santos

我使用过 MVP 和 MVC,虽然我们作为开发人员倾向于关注这两种模式的技术差异,但在 IMHO 中,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


P
Peter Mortensen

在 MVP 中,视图从演示者中提取数据,演示者从模型中提取和准备/规范化数据,而在 MVC 中,控制器通过视图中的推送从模型中提取数据并设置。

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

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

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

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

然后,您可以将许多不同类型的演示者绑定到视图,所有演示者都必须具有 Maker 属性 - 它可以是飞机、火车或其他任何东西,视图无关紧要。视图从演示者那里获取数据——不管是哪一个——只要它实现了一个约定的接口。

这个绑定框架,如果你把它拆掉,它实际上是控制器:-)

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

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

结论 - MVP 和 MVC 都是 UI 模式的解耦,但 MVP 通常使用绑定框架,其底层是 MVC。因此,MVP 处于比 MVC 更高的架构级别,并且是 MVC 之上的包装器模式。


H
Hibou57

我谦虚的短视:MVP 用于大规模,MVC 用于小规模。使用 MVC,我有时会觉得 V 和 C 可能被视为单个不可分割组件的两侧,而不是直接绑定到 M,而当缩小到更短的比例时,如 UI 控件和基本小部件,不可避免地会落入这一点。在这种粒度级别上,MVP 没有什么意义。相反,当一个更大的规模时,适当的接口变得更加重要,与明确的职责分配相同,MVP 出现了。

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


J
Jboy Flaga

我认为 Erwin Vandervalk(以及随附的 article)的这张图片是对 MVC、MVP 和 MVVM、它们的相似之处和不同之处的最佳解释。 article 不会出现在“MVC、MVP 和 MVVM”查询的搜索引擎结果中,因为文章的标题不包含“MVC”和“MVP”字样;但我认为这是最好的解释。

https://i.stack.imgur.com/Y82D3.png

article 也符合 Bob Martin 叔叔在他的一次演讲中所说的:MVC 最初是为小型 UI 组件设计的,而不是为系统架构设计的)


o
onmyway133

https://i.stack.imgur.com/aebJI.png

这个谈话droidcon NYC 2017 - Clean app design with Architecture Components阐明了这一点

https://i.stack.imgur.com/wPqMA.png


在 MVC 中,模型永远不会直接从视图中调用
这是一个不准确的答案。不要被误导。正如@rodi 所写,视图和模型之间没有交互。
MVC 图像不准确或充其量具有误导性,请不要关注此答案。
@Jay1b 你认为什么 MVC 是“正确的”?这个答案是关于原始 MVC 的。还有许多其他 MVC(如 iOS 中)已更改以适应平台,例如 UIKit
箭头是什么意思?
M
Mostafa Wael

MVC(模型-视图-控制器)

在 MVC 中,Controller 是负责人!控制器根据一些事件/请求被触发或访问,然后管理视图。

MVC 中的视图实际上是无状态的,控制器负责选择要显示的视图。

例如:当用户点击“Show MyProfile”按钮时,Controller 被触发。它与模型通信以获取适当的数据。然后,它会显示一个类似于配置文件页面的新视图。控制器可以从模型中获取数据并将其直接提供给视图(如上图所示),或者让视图从模型本身获取数据。

MVP(模型-视图-演示者)

在 MVP 中,视图是负责人!每个 View 调用它的 Presenter 或者有一些 Presenter 监听的事件。

MVP 中的视图不实现任何逻辑,Presenter 负责实现所有逻辑并使用某种接口与视图通信。

例如:当用户单击“Save”按钮时,View 中的事件处理程序将委托给 Presenter 的“OnSave”方法。 Presenter 将执行所需的逻辑并与模型进行任何所需的通信,然后通过其接口回调视图,以便视图可以显示保存已完成。

MVC 与 MVP

MVC 不让 View 负责,View 充当 Controller 可以管理和指导的从属设备。

在 MVC 中,视图是无状态的,而 MVP 中的视图是有状态的并且可以随时间变化。

在 MVP 中,视图没有逻辑,我们应该尽可能让它们保持沉默。另一方面,MVC 中的视图可能具有某种逻辑。

在 MVP 中,Presenter 与 View 分离,并通过接口与其对话。这允许在单元测试中模拟视图。

在 MVP 中,视图与模型完全隔离。但是,在 MVC 中,视图可以与模型通信,以使其与最新数据保持同步。

https://i.stack.imgur.com/Yttsn.png


C
Clive Jefferies

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


我投了反对票,因为 afaik 模型对 MVC 中的视图一无所知,并且无法在您编写时直接更新它。
查看 Wikipedia 上的 MVC,这正是它的工作原理。
无论读者喜欢与否,通过谷歌搜索可以找到大量资源,在 MVC 中,视图订阅了模型的更新。在某些情况下甚至可能是控制器,因此会调用此类更新。如果你不喜欢这样,那么就去抱怨那些文章,或者引用你认为是唯一合法来源的“圣经”,而不是对那些只是传递其他可用信息的答案投反对票!
措辞肯定可以改进,但视图确实订阅了 MVC 中模型的更改。模型不需要知道 MVC 中的视图。
R
Rahul

this 个来自 Bob 叔叔的精彩视频,他简要介绍了 MVCMVP 在最后。

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

在 MVC 中,我们通过接口(边界)来粘合不同的层。控制器是我们架构的插件,但它没有这样的限制来强加显示什么。从这个意义上说,MVP 是一种 MVC,其概念是视图可通过适配器插入控制器。

我希望这有助于更好。


Bob 叔叔的要点:最初由 Trygve Reenskaug 发明时,MVC 用于每个小部件而不是整个表单。
H
Hugo Rafael Azevedo

您忘记了 Action-Domain-Responder (ADR)。

如上图所示,MVC 中的模型和视图之间存在直接关系/链接。在 Controller 上执行一个动作,它将在 Model 上执行一个动作。模型中的那个动作,将触发视图中的反应。当模型的状态发生变化时,视图总是会更新。

有些人一直忘记 MVC was created in the late 70",以及 Web 只是在 80 年代末/90 年代初创建的。 MVC 最初不是为 Web 创建的,而是为桌面应用程序创建的,其中控制器、模型和视图将共存。

因为我们使用的 Web 框架(例如:.Laravel)仍然使用相同的命名约定(模型-视图-控制器),所以我们倾向于认为它一定是 MVC,但实际上它是另外一回事。

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

注意:维基百科声明“然而,每个 ADR 操作都由单独的类或闭包表示。”。这不一定是真的。多个Action可以在同一个Controller中,模式还是一样的。


C
Chinmai Kulkarni

简单来说,

在 MVC 中,View 具有 UI 部分,它调用控制器,控制器又调用模型和模型,然后将事件返回给视图。

在 MVP 中,View 包含 UI 并为实现部分调用 Presenter。演示者直接调用视图以更新 UI 部分。包含业务逻辑的模型由演示者调用,并且与视图没有任何交互。所以这里的主持人做了大部分的工作:)


R
Rahul

MVP

MVP 代表模型 - 视图 - 演示者。这出现在 2007 年初,微软推出了 Smart Client Windows 应用程序。

演示者在 MVP 中充当监督角色,将视图事件和模型中的业务逻辑绑定在一起。

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

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

优点:视图只有 UI 没有任何逻辑 高水平的可测试性

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

MVC

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

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

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

缺点:如果尝试在同一个控制器中渲染多个视图,有时控制器的工作量太大。