当超越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上下文中的模型-视图-视图-模型模式的博客。

其他回答

鲍勃叔叔的这段视频很好,他在最后简要解释了MVC和MVP。

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

在MVC中,我们通过接口(边界)来粘合不同的层。控制器是我们体系结构的一个插件,但它对显示内容没有任何限制。从这个意义上讲,MVP是一种MVC,其概念是视图可以通过适配器插入控制器。

我希望这有助于更好。

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

用户:单击…

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

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

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

(视图调用演示者|控制器…)[MMVP|MVC]

视图:嗨,演示者|控制器,用户刚刚单击了搜索按钮,我该怎么办?[MVP|MVC]

演示者|控制器:嘿,View,那个页面上有搜索词吗?[MVP|MVC]

视图:是的,…这里是…“钢琴”[MMVP|MVC]

演示者|控制器:谢谢查看,……同时我正在查找模型上的搜索项,请向他/她显示进度条[MVP|MVC]

(演示者|控制器正在调用模型…)[MMVP|MVC]

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

模型:嘿,演示者|控制器,让我检查一下…〔MVP|MVC〕

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

(过了一会儿…)

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

模型:我为您找到了一个列表,演示者,这里是JSON格式的“[{“name”:“Piano Teacher”,“year”:2001},{“name:”Piano”,“year”:1993}]”[MVP]

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

(演示者|控制器感谢模型并返回视图)[MMVP|MVC]

演示者:感谢等待View,我为您找到了一个匹配结果列表,并以可呈现的格式排列:[“Piano Teacher 2001”,“Piano 1993”]。请在垂直列表中向用户显示。也请现在隐藏进度条[MMVP]

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

观点:非常感谢演示者MVP

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

如果你感兴趣的话,我一直在写一系列关于应用程序架构模式(MVC、MVP、MVVP、干净架构……)的文章,并在这里附上Github repo。尽管该示例是为android编写的,但其基本原理可以应用于任何介质。

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

本期演讲droidcon NYC 2017-带有架构组件的干净应用程序设计阐明了这一点

MVP不一定是视图负责的场景(例如,参见Taligent的MVP)。我觉得很不幸的是,人们仍在宣扬这是一种模式(主管视图),而不是一种反模式,因为它与“这只是一种观点”(实用主义程序员)相矛盾。“这只是一个视图”表示,向用户显示的最终视图是应用程序的次要关注点。微软的MVP模式使视图的重用变得更加困难,并方便地为微软的设计师提供了避免不良做法的借口。

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

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

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

MVP=模型视图演示者MVC=模型视图控制器两种演示模式。它们将模型(考虑域对象)、屏幕/网页(视图)和用户界面(演示者/控制器)之间的依赖关系分开它们在概念上相当相似,人们根据口味对演示者/控制器进行不同的初始化。这里有一篇关于差异的精彩文章。最值得注意的是MVC模式具有更新视图的模型。