当超越RAD(拖放和配置)构建用户界面的方式时,许多工具都鼓励您使用三种设计模式,即模型视图控制器、模型视图演示器和模型视图视图模型。我的问题有三个部分:

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


当前回答

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

使用被动视图时,视图通常实现一个细粒度的接口,其中财产或多或少直接映射到底层UI小部件。例如,您可能有一个具有诸如Name和Address等财产的ICustomerView。

您的实现可能如下所示:

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

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

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

MVP的第三个“味道”(或者有人可能会称之为一个单独的模式)是演示模型(或者有时称为模型-视图-视图模型)。与MVP相比,你将M和P“合并”为一个类。您有UI小部件数据绑定到的客户对象,但也有其他UI特定字段,如“IsButtonEnabled”或“IsReadOnly”等。

我认为我找到的最好的UI架构资源是Jeremy Miller在the Build Your Own CAB系列目录上发表的一系列博客文章。他涵盖了MVP的所有风格,并展示了实现它们的C#代码。

我也在YouCard网站上写过关于Silverlight上下文中的模型-视图-视图-模型模式的博客。

其他回答

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

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

这两种方法都支持TDD,并有其优缺点。

关于如何选择其中一个IMHO的决定应该基于在ASP.NET 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中,控制器通过在视图中推送从模型中获取数据并进行设置。

在MVP中,您可以使用一个视图来处理多种类型的演示者,也可以使用单个演示者来处理不同的多个视图。

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

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

因此,例如,如果模型是一辆汽车,那么演示者是某种汽车演示者,向视图公开汽车的财产(年份、制造商、座位等)。视图知道名为“car maker”的文本字段需要显示演示者maker属性。

然后,您可以将许多不同类型的演示者绑定到视图中,所有演示者都必须具有Maker属性-它可以是飞机、火车或其他任何类型的视图,视图都不在乎。视图从演示者(无论是哪一个)获取数据,只要它实现了一个商定的接口。

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

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

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

结论:MVP和MVC都是UI模式的解耦,但MVP通常使用一个绑定框架,该框架的底层是MVC。THUS MVP的体系结构级别高于MVC,并且是MVC之上的包装模式。

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

这里讨论了MVC与MVP之间的区别。

所做的区别在于,在MVC应用程序中,视图和控制器传统上与模型交互,而不是彼此交互。

MVP设计让演示者访问模型并与视图交互。

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

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

不久前,我在博客中引用了托德·斯奈德(Todd Snyder)关于两者区别的精彩文章:

以下是模式:MVP模式视图与模型的耦合更加松散。演示者是负责将模型绑定到视图。更容易进行单元测试,因为与视图的交互是通过的接口通常视图到演示者的映射是一对一。复杂视图可能具有多主持人。MVC模式控制器基于行为,可以在意见可以负责确定要显示的视图

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