当超越RAD (拖放和配置)构建用户界面的方式时,许多工具鼓励您使用三种设计模式,分别称为Model-View-Controller , Model-View-Presenter和Model-View-ViewModel 。 我的问题包括三个部分:
- 这些模式解决了哪些问题?
- 它们有何相似之处?
- 它们有何不同?
#1楼
模型视图演示者
在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中,视图中的每个动作都与对控制器的调用以及一个动作相关联。 在网络中,每个动作都涉及对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 (前棱镜)的复合应用指南中有关于单独的表示模式的部分
#2楼
两者都是试图将表示和业务逻辑分离,将业务逻辑与UI方面分离的模式
在架构上,MVP是基于页面控制器的方法,而MVC是基于前端控制器的方法。 这意味着在MVP标准Web表单页面中,生命周期只是通过从后面的代码中提取业务逻辑来增强。 换句话说,page是服务http请求的请求。 换句话说,MVP IMHO是Web表单进化类型的增强功能。 另一方面,MVC完全改变了游戏,因为在页面加载之前,请求类被控制器类拦截,在那里执行业务逻辑,然后在控制器处理刚转储到页面的数据(“视图”)的最终结果中从某种意义上说,MVC(至少对我而言)对路由引擎增强的MVP的Supervising Controller风格很有帮助
他们俩都支持TDD,并且有缺点和缺点。
如何选择其中一个恕我直言的决定应基于一个人在ASP NET Web表单类型的Web开发上投入了多少时间。 如果有人认为自己擅长于Web表单,我建议MVP。 如果人们对页面生命周期之类的事情不太满意,那么MVC可能是解决问题的一种方法。
这是另一个博客文章链接,提供有关此主题的更多详细信息
#3楼
我的简短观点是:MVP适用于大规模,而MVC适用于小规模。 使用MVC时,我有时会感觉到V和C可以看作是单个不可分割组件的两侧,而是直接绑定到M上,当降低到更小的比例时(如UI控件和基本小部件),不可避免地会遇到这种情况。 在这种粒度级别上,MVP毫无意义。 相反,当规模扩大时,正确的接口就变得更加重要,明确分配职责也是如此,这就是MVP。
另一方面,当平台特性有利于组件之间的某种关系时,例如在Web上,实现MVC似乎比MVP更容易,这种经验法则的权重可能很小。
#4楼
在MVP中,视图从演示者中提取数据,演示者从模型中提取数据并对其进行准备/归一化;而在MVC中,控制器通过推入视图从模型中进行数据设置。
在MVP中,您可以具有一个与多种类型的演示者一起使用的视图,以及一个与不同的多种视图一起使用的演示者。
MVP通常使用某种绑定框架,例如Microsoft WPF绑定框架或用于HTML5和Java的各种绑定框架。
在这些框架中,UI / HTML5 / XAML知道每个UI元素显示的演示者的属性,因此,当您将视图绑定到演示者时,视图将查找属性,并知道如何从它们中绘制数据以及如何在用户更改UI中的值时进行设置。
因此,例如,如果模型是一辆汽车,那么演示者就是某种汽车演示者,将汽车属性(年份,制造商,座位等)暴露给视图。 该视图知道称为“汽车制造商”的文本字段需要显示Presenter Maker属性。
然后,您可以将许多不同类型的演示者绑定到视图,所有演示者都必须具有Maker属性-它可以是飞机,火车或其他任何东西,该视图无关紧要。 只要实现了约定的界面,该视图就会从演示者那里获取数据-无论哪种方式。
这个绑定框架,如果将其剥离,实际上是控制器:-)
因此,您可以将MVP视为MVC的演进。
MVC很棒,但是问题在于通常每个视图都有它的控制器。 控制器A知道如何设置视图A的字段。如果现在,您希望视图A显示模型B的数据,则需要控制器A知道模型B,或者需要控制器A接收带有接口的对象-就像仅MVP不带绑定,否则您需要在Controller B中重写UI设置代码。
结论-MVP和MVC都是UI模式的分离,但MVP通常使用下面的MVC绑定框架。 THUS MVP的体系结构级别高于MVC,并且其包装模式高于MVC。
#5楼
这是这些设计模式的许多变体的过度简化,但这就是我想考虑两者之间的差异的方式。
MVC

最有价值球员

来源:oschina
链接:https://my.oschina.net/stackoom/blog/3137269