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

时间:2020-03-05 18:37:42  来源:igfitidea点击:

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

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

解决方案

回答

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

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

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

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

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

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

回答

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

Here are the key differences between
  the patterns:
  
  MVP Pattern
  
  
  View is more loosely coupled to the model. The presenter is
  responsible for binding the model to
  the view.
  Easier to unit test because interaction with the view is through
  an interface
  Usually view to presenter map one to one. Complex views may have
  multi presenters.
  
  
  MVC Pattern
  
  
  Controller are based on behaviors and can be shared across
  views
  Can be responsible for determining which view to display

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

回答

  • MVP =模型视图演示者
  • 它们在概念上非常相似,人们根据喜好不同地初始化Presenter / Controller。
  • 关于差异的一篇很棒的文章在这里。最值得注意的是,MVC模式具有更新视图的模型。

回答

MVP:视图负责。

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

MVC:控制器负责。

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

回答

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

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

实现可能看起来像这样:

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

Presenter类将与模型对话,然后将其"映射"到视图。这种方法称为"被动视图"。好处是视图易于测试,并且更易于在UI平台(Web,Windows / XAML等)之间移动。缺点是我们不能利用数据绑定之类的东西(在WPF和Silverlight之类的框架中确实非常强大)。

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

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

我认为,我发现有关UI体系结构的最佳资源是Jeremy Miller在"构建自己的CAB系列目录"中撰写的一系列博客文章。他涵盖了MVP的所有方面,并展示了Ccode来实现它们。

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

回答

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

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

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

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

回答

模型视图展示者

在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中,视图中的每个动作都与对Controller的调用以及一个动作相关联。在网络中,每个动作都涉及对URL的调用,在该URL的另一侧有一个Controller响应。该控制器完成处理后,将返回正确的视图。该序列在应用程序的整个生命周期中都以这种方式继续:

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

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

展示模型

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

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

回答

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

回答

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

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

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

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

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

回答

我不明白的是为什么数据绑定必须降低可测试性。我的意思是,一个视图实际上基于一个或者多个数据库视图,对吗?在不同视图中的行之间可能存在连接。另外,我们可以谈论面向对象而不是关系,但是实际上并没有改变任何东西-我们仍然有一个或者多个不同的数据实体。

如果我们将编程视为数据结构+算法,那么最好使数据结构尽可能明确,然后开发每个算法都依赖于尽可能少的数据,并且算法之间的耦合最少的算法。 ?

我在这里感觉到Java风格的FactoryFactoryFactory思想模式-我们希望到处都具有多个视图,多个模型和多个自由度。这就好像是MVC和MVP以及诸如此类的背后推动力。现在让我问一个问题:我们为此付出的成本(而且绝对肯定有成本)多久值得一次?

我也没有看到有关如何有效管理HTTP请求之间的状态的讨论。我们难道不是从功能界人士那里学到的(以及命令式意大利面条所犯的大量错误),国家是邪恶的,应该被最小化(并且在使用时应该被很好地理解)?

我看到MVC和MVP术语的用法很多,但没有太多证据表明人们对此持批评态度。显然,问题出在"他们","我"或者两者兼而有之。