design patterns -MVP和MVC有什么区别?

Translate

当超越RAD(拖放和配置)多种工具鼓励您构建用户界面的方式,您可能会遇到以下三种设计模式:模型视图控制器, 模型视图展示者模型-视图-视图模型。我的问题包括三个部分:

  1. 这些模式解决了哪些问题?
  2. 它们有何相似之处?
  3. 它们有何不同?
This question and all comments follow the "Attribution Required."

所有的回答

Translate

模型视图展示者

最有价值球员,演示者包含视图的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响应。该控制器完成处理后,将返回正确的视图。该序列在应用程序的整个生命周期中都以这种方式继续:

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

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

展示模型

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

有一个有关表示模型的MSDN文章以及WPF的复合应用指南(前棱镜)关于分离的演示模式

来源
Translate

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

MVC

MVC

最有价值球员

enter image description here

来源
Translate

我前一段时间在博客上对此进行了引用托德·斯奈德(Todd Snyder)关于两者差异的出色文章:

这是两种模式之间的主要区别:

MVP模式

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

MVC模式

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

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

来源
Translate

这是代表通信流程的插图

enter image description here

enter image description here

来源
Translate

MVP是必然是由视图负责的场景(例如,请参阅Taligent的MVP)。
我发现不幸的是,人们仍然将其作为一种模式(负责视图)而不是反模式来进行讲道,因为它与“这只是一个视图”(实用程序员)相矛盾。 “这只是一个视图”指出向用户显示的最终视图是该应用程序的第二要务。微软的MVP模式使视图的重用变得更加困难,并且方便地原谅微软的设计师鼓励不良做法。

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

考虑这个非常令人兴奋的文章,全面列出了许多这些不同的实现。您可能会注意到,他们基本上都在做相同的事情,但略有不同。

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

来源
Translate

MVP:视图负责。

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

MVC:控制器负责。

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

来源
AVI
Translate

enter image description here

MVC(模型视图控制器)

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

MVP(模型视图演示者)

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

欲了解更多参考

来源
Translate

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

用户:单击单击…

视图: 那是谁? [最有价值球员|MVC]

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

视图:好吧,稍等片刻……。 [最有价值球员|MVC]

( 视图称呼主持人|控制者…)[最有价值球员|MVC]

视图:嘿主持人|控制者,用户刚刚单击搜索按钮,我该怎么办? [最有价值球员|MVC]

主持人|控制者:嘿视图,该页面上有搜索词吗? [最有价值球员|MVC]

视图:是的,这里是……“钢琴” [最有价值球员|MVC]

主持人: 谢谢视图,...同时,我正在模型,请向他/她展示进度条[最有价值球员|MVC]

( 主持人|控制者正在呼叫模型…)[最有价值球员|MVC]

主持人|控制者:嘿模型,您是否与此搜索词匹配?:“ piano” [最有价值球员|MVC]

模型:嘿主持人|控制者,让我检查一下……[最有价值球员|MVC]

( 模型正在查询电影数据库...)[最有价值球员|MVC]

( 过了一会儿 ... )

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

模型:我为您找到了一个清单,主持人,这里是JSON“ [{“ name”:“ Piano Teacher”,“ year”:2001},{“ name”:“ Piano”,“ year”:1993}]“] [最有价值球员]

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

(主持人|控制者谢谢模型然后回到视图)[最有价值球员|MVC]

主持人:感谢您的等待视图,我找到了一个适合您的匹配结果列表,并以一种合适的格式进行排列:[“ Piano Teacher 2001”,“ Piano 1993”]。请在垂直列表中向用户显示。另外,请立即隐藏进度栏[最有价值球员]

控制者:感谢您的等待视图, 我问过了模型关于您的搜索查询。它说已找到匹配结果的列表,并将其存储在其实例内部的名为“ searchResultsList”的变量中。您可以从那里得到它。另外,请立即隐藏进度栏[MVC]

视图: 非常感谢你主持人 [最有价值球员]

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

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

来源
Translate
  • MVP =模型视图呈现器
  • MVC =模型-视图-控制器

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

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

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

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

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

Presenter类将与模型对话,并将其“映射”到视图。这种方法称为“被动视图”。好处是视图易于测试,并且更易于在UI平台(Web,Windows / XAML等)之间移动。缺点是您无法利用数据绑定之类的功能(这是强大的框架WPF银光).

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

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

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

我还通过博客在Silverlight的上下文中撰写了有关Model-View-ViewModel模式的博客。再次访问YouCard:实现ViewModel模式.

来源
Translate

模型视图控制器

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

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

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

enter image description here

模型视图展示者

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

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

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

是什么区别之间MVC最有价值球员模式?

MVC模式

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

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

MVP模式

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

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

  • 通常视图与演示者之间是一对一的映射。复杂的视图可能有多个演示者。

来源
Translate

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

The Combined Pattern

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

来源
Translate

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

有一个讨论这里关于MVC与MVP之间的差异。

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

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

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

若要了解MVP与ASP.NET MVC的区别,请查看这个MIX演示斯科特·汉塞尔曼(Scott Hanselman)撰写。

来源
Translate

两者都是试图将表示和业务逻辑分开,将业务逻辑与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

来源
Translate

我曾经使用过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

来源
Translate

在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。

来源
Translate

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

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

来源
Translate

MVC有很多版本,此答案与Smalltalk中的原始MVC有关。简而言之,它是image of mvc vs mvp

这个话题droidcon NYC 2017-使用Architecture Components进行简洁的应用程序设计澄清它

enter image description here enter image description here

来源
Translate

这个Bob叔叔的精彩视频,最后他简要介绍了MVC和MVP。

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

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

希望这会有所帮助。

来源
Translate

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

来源
Translate

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

image explaining MVC, MVP and MVVM - by Erwin Vandervalk

文章也符合鲍勃·马丁叔叔在他的一次演讲中所说的:MVC最初是为小型UI组件而不是为系统体系结构设计的。

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

最有价值球员

MVP代表模型-视图呈现器。在2007年初,Microsoft引入了Smart Client Windows应用程序时,就出现了这种情况。

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

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

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

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

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

MVC

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

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

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

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

来源
上一个问题:
监视特定的RSS