当超越RAD(拖放和配置)构建用户界面的方式时,许多工具都鼓励您使用三种设计模式,即模型视图控制器、模型视图演示器和模型视图视图模型。我的问题有三个部分:
这些模式解决了什么问题?它们有什么相似之处?它们有何不同?
当超越RAD(拖放和配置)构建用户界面的方式时,许多工具都鼓励您使用三种设计模式,即模型视图控制器、模型视图演示器和模型视图视图模型。我的问题有三个部分:
这些模式解决了什么问题?它们有什么相似之处?它们有何不同?
当前回答
不久前,我在博客中引用了托德·斯奈德(Todd Snyder)关于两者区别的精彩文章:
以下是模式:MVP模式视图与模型的耦合更加松散。演示者是负责将模型绑定到视图。更容易进行单元测试,因为与视图的交互是通过的接口通常视图到演示者的映射是一对一。复杂视图可能具有多主持人。MVC模式控制器基于行为,可以在意见可以负责确定要显示的视图
这是我能在网上找到的最好的解释。
其他回答
这两种模式都试图分离表示和业务逻辑,将业务逻辑与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
MVP代表模型-视图-演示者。2007年初,微软推出了Smart Client windows应用程序。
演示者在MVP中充当监督角色,MVP绑定模型中的视图事件和业务逻辑。
视图事件绑定将从视图界面在Presenter中实现。
视图是用户输入的发起者,然后将事件委派给演示者,演示者处理事件绑定并从模型中获取数据。
赞成的意见:视图只有UI,没有任何逻辑高水平的可测试性
欺骗:实现事件绑定时有点复杂,工作量更大
MVC
MVC代表模型视图控制器。控制器负责创建模型并使用绑定模型渲染视图。
控制器是启动器,它决定渲染哪个视图。
赞成的意见:强调单一责任原则高水平的可测试性
欺骗:如果试图在同一控制器中渲染多个视图,有时控制器的工作量太大。
我简短的观点是:MVP适用于大范围,MVC适用于小范围。有了MVC,我有时会觉得V和C可能被看作是一个不可分割的组件的两面,而不是直接绑定到M,当向下扩展到较短的规模时,如UI控件和基本控件时,必然会出现这种情况。在这种粒度级别上,MVP意义不大。相反,当一个人走向更大的规模时,适当的界面变得更重要,同样,明确的职责分配也同样重要,MVP就来了。
另一方面,当平台特性有助于组件之间的某种关系时,例如在web上,MVC的实现似乎比MVP更容易。
这个问题有很多答案,但我觉得需要一些非常简单的答案来清楚地比较两者。以下是我在用户在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编写的,但其基本原理可以应用于任何介质。