【问题标题】:What are MVP and MVC and what is the difference?什么是 MVP 和 MVC,有什么区别?
【发布时间】:2010-09-05 08:21:33
【问题描述】:

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

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

【问题讨论】:

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

标签: user-interface model-view-controller design-patterns terminology mvp


【解决方案1】:

模型-视图-演示者

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 的另一端有一个控制器进行响应。一旦该控制器完成其处理,它将返回正确的视图。该顺序在应用程序的整个生命周期中以这种方式持续:

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

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

演示模型

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

Composite Application Guidance for WPF(前棱镜)中有一个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 处理View 生成的 HTML 被发送到客户端 -- 所以,Viewbackend 的一部分,用户永远无法直接访问它,如果你在任何地方遇到相反,然后将其视为 MVC 扩展(甚至违反)。 @Panzercrisis,这不同于MVP(就像在Android OS 中使用的那样),其中actions route through the View to the Presenter 和用户可以直接访问View
  • 作者在谈到 MVC 时所描述的不是原始的 Smalltalk MVC(其流程是三角形的),而是控制器使用模型渲染视图并将其返回给用户的“Web MVC” .我认为这是值得注意的,因为这会造成很多混乱。
【解决方案2】:

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

MVC

MVP

【讨论】:

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

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

以下是两者之间的主要区别 模式:

MVP 模式

  • 视图与模型的耦合更加松散。主持人是 负责将模型绑定到 视图。
  • 更容易进行单元测试,因为与视图的交互是通过 一个界面
  • 通常一对一地查看演示者映射。复杂的视图可能有 多位演示者。

MVC 模式

  • 控制器是基于行为的,可以共享 观看次数
  • 可以负责确定要显示的视图

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

【讨论】:

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

这里是代表通信流程的插图



【讨论】:

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

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

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

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

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

【讨论】:

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

MVP:视图负责。

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

MVC:控制器负责。

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

【讨论】:

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

MVC(模型视图控制器)

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

MVP(模型视图展示器)

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

了解更多Reference

【讨论】:

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

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

用户:点击点击……

查看:那是谁? [MVP|MVC]

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

查看:好的,等一下……。 [MVP|MVC]

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

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

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

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

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

(Presenter|Controller 正在调用 Model ...) [MVP|MVC强>]

Presenter|Controller:嘿Model,你有这个搜索词匹配吗?:“piano” [MVP |MVC]

Model:嘿Presenter|Controller,让我看看……[MVP|MVC]

Model 正在对电影数据库进行查询……)[MVP|MVC]

(过了一会儿……)

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

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

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

Presenter|Controller感谢Model,然后回到View)[MVP|MVC]

Presenter:感谢您的等待查看,我为您找到了匹配结果列表,并将它们排列成一个像样的格式:["Piano Teacher 2001","Piano 1993 年”]。请在垂直列表中显示给用户。另外请现在隐藏进度条[MVP]

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

观点:非常感谢Presenter [MVP]

查看:谢谢“控制器”[MVC] (现在 View 正在质疑自己:我应该如何将我从 Model 获得的结果呈现给用户?电影的制作年份应该排在第一个还是最后一个.. .? 它应该在垂直列表还是水平列表中?...)

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

【讨论】:

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

模型-视图-控制器

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

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

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

模型-视图-演示者

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

如果您想查看简单实现的示例,请查看 thisGitHub发帖

从数据库中查询和显示用户列表的具体工作流程可以这样工作:

MVCMVP 模式之间的区别是什么?

MVC 模式

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

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

MVP 模式

  • 视图与模型的耦合更加松散。 Presenter 负责将模型绑定到视图。

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

  • 通常一对一地查看演示者映射。复杂视图可能有多个演示者。

【讨论】:

  • 不,在 mvc 中视图和模型之间没有直接联系。你的图表是错误的。
  • @Özgür 实际上有而且图表是正确的。
【解决方案10】:
  • MVP = 模型-视图-演示者
  • MVC = 模型-视图-控制器

    1. 两种呈现模式。它们分离了模型(想想域对象)、屏幕/网页(视图)以及 UI 的行为方式(演示者/控制器)之间的依赖关系
    2. 它们在概念上非常相似,人们根据喜好以不同的方式初始化 Presenter/Controller。
    3. 一篇关于差异的精彩文章是here。最值得注意的是,MVC 模式让模型更新视图。

【讨论】:

  • 模型更新视图。而且这仍然是一个解耦系统?
【解决方案11】:

另外值得记住的是,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 上下文中模型-视图-视图模型模式的博客。

【讨论】:

    【解决方案12】:

    这两个框架都旨在分离关注点 - 例如,与数据源(模型)、应用程序逻辑(或将此数据转化为有用信息)(控制器/演示者)和显示代码(视图)的交互。在某些情况下,该模型还可用于将数据源转换为更高级别的抽象。 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 作为具体示例。
    【解决方案13】:

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

    在架构上,MVP 是基于页面控制器的方法,而 MVC 是基于前端控制器的方法。 这意味着在 MVP 标准网页表单中,页面生命周期只是通过从后面的代码中提取业务逻辑来增强。换句话说,页面是服务于 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

    【讨论】:

      【解决方案14】:

      我同时使用了 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

      【讨论】:

        【解决方案15】:

        在 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 之上的包装器模式。

        【讨论】:

          【解决方案16】:

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

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

          【讨论】:

            【解决方案17】:

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

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

            【讨论】:

              【解决方案18】:

              MVC 有很多版本,这个答案是关于 Smalltalk 中的原始 MVC。简而言之,就是

              这个谈话droidcon NYC 2017 - Clean app design with Architecture Components澄清了它

              【讨论】:

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

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

              【讨论】:

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

              有来自 Bob 叔叔的 this 精彩视频,他在最后简要解释了 MVCMVP

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

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

              我希望这会有所帮助。

              【讨论】:

              • 鲍勃叔叔的重要观点:最初由 Trygve Reenskaug 发明时,MVC 用于每个小部件而不是整个表单。
              【解决方案21】:

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

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

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

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

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

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

              【讨论】:

                【解决方案22】:

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

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

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

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

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

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

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

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

                MVC 与 MVP

                • MVC 不让 View 负责,View 充当 Controller 可以管理和指挥的从属设备。
                • 在 MVC 中,视图是无状态的,而 MVP 中的视图是有状态的并且可以随时间变化。
                • 在 MVP 中,视图没有逻辑,我们应该尽可能让它们保持沉默。另一方面,MVC 中的视图可能具有某种逻辑。
                • 在 MVP 中,Presenter 与 View 分离,并通过接口与其对话。这允许在单元测试中模拟视图。
                • 在 MVP 中,视图与模型完全隔离。但是,在 MVC 中,Views 可以与 View 进行通信以使其跟上最 最新数据。

                【讨论】:

                  【解决方案23】:

                  简而言之,

                  • 在 MVC 中,View 有 UI 部分,它调用控制器,控制器又调用模型和模型,然后将事件返回给视图。
                  • 在 MVP 中,View 包含 UI 并调用 Presenter 来实现部分。演示者直接调用视图以更新 UI 部分。 包含业务逻辑的模型由演示者调用,并且与视图没有任何交互。所以这里的演示者完成了大部分工作:)

                  【讨论】:

                    【解决方案24】:

                    MVP

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

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

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

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

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

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

                    MVC

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

                    Controller 是发起者,它决定渲染哪个视图。

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

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

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2011-03-14
                      • 2011-09-10
                      • 2022-08-17
                      • 1970-01-01
                      • 2011-06-05
                      • 2019-03-08
                      相关资源
                      最近更新 更多