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

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


当前回答

MVC(模型视图控制器)

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

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

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

MVP(模型视图演示者)

在MVP中,视图是负责人!每个视图都会调用其演示者或演示者收听的某些事件。

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

例如:当用户单击“保存”按钮时,视图中的事件处理程序将委派给演示者的“OnSave”方法。演示者将执行所需的逻辑,并与模型进行任何所需的通信,然后通过其界面调用视图,以便视图显示保存已完成。

MVC与MVP

MVC并没有让视图负责,视图充当控制器可以管理和指导的从属对象。在MVC中,视图是无状态的,而MVP中的视图是有状态的,可以随时间变化。在MVP中,视图没有逻辑,我们应该尽可能让它们保持沉默。另一方面,MVC中的视图可能有某种逻辑。在MVP中,演示者与视图分离,并通过接口与视图对话。这允许在单元测试中模拟视图。在MVP中,视图与模型完全隔离。然而,在MVC中,视图可以与模型通信,以使其与最新的最新数据。

其他回答

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

以下是模式: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和MVP。

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

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

我希望这有助于更好。

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

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

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

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

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

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