Presenter、Presentation Model、ViewModel 和 Controller 之间有什么区别?

64
我对这些模式的工作方式有很好的了解,并知道它们之间的一些细微差异,但它们真的有那么不同吗?
在我看来,Presenter、Presentation Model、ViewModel和Controller本质上是相同的概念。
为什么我不能将所有这些概念都归类为控制器?我觉得这可能会大大简化整个概念。
有人能清晰地描述它们之间的区别吗?
我想澄清,我确实理解这些模式的工作原理,并在某种技术上实现了它们中的大多数。我真正想要的是有人分享他们对其中一个模式的经验,以及为什么他们不认为他们的ViewModel是一个Controller,例如。
我会给予一些声望点数作为奖励,但我正在寻找一个真正好的答案。

这个答案也适合那些对它们进行非常简单比较感兴趣的人:https://stackoverflow.com/a/50390500/4514796 - Ali Nem
6个回答

76
除了已经提到的伟大读物(Fowler和Miller)以外,就您对控制器/演示者等的差异之点的回答,从开发者的角度来看:
MVC中的“控制器”: - “控制器”是由用户交互而调用的实际组件。开发人员不必编写代码来委托对“控制器”的调用。 - “控制器”从“视图/上下文/包/其他什么东西”中以某种方式获取当前值,但您不会真正说它与“视图”进行交互。 - “控制器”最终决定要向用户显示哪个“视图”。在这方面,“控制器”显示了应用程序导航工作流程的显式概念。
MVP中的“演示者”: - “演示者”有被“视图”调用的方法,这是实际接收用户交互控制的组件。开发人员必须在“视图”中编写一些代码才能调用“演示者”。 - “演示者”以某种方式从“视图”获取当前值或在调用时收到这些值。 “演示者”调用“视图”的方法以设置其状态(Josh Smith称之为“填充它”)。由“演示者”调用的“视图”方法可能在其主体中执行几个小设置。 - “演示者”没有明确显示应用程序工作流的概念。通常认为是将控制返回到调用的“视图”。
PM中的“PresentationModel”: - “PresentationModel”有被“视图”调用的方法,这是实际接收用户交互控制的组件。开发人员必须在“视图”中编写一些代码才能调用“PresentationModel”。 - 与“演示者”相比,“PresentationModel”与“视图”的通信更加“啰嗦”。它还包含更多逻辑,以确定要应用于“视图”的所有设置的值,并实际将这些设置应用于“视图”。那些由“PresentationModel”调用的“视图”方法几乎没有逻辑。
  • 在MVVM中,PresentationModel并没有明确展示应用程序工作流的概念。通常认为它会将控制权返回给调用视图。

  • MVVM中的ViewModel:

    • ViewModel有被View调用的方法和属性(设置),即实际接收用户交互控制的组件。开发人员必须在View中编写一些(声明性)代码才能调用ViewModel。

    • 与PresentationModel相比,ViewModel与View之间的通信不是显式的(即它不会频繁地调用View,而是由框架处理)。但它有许多属性与View设置1对1的映射。它仍然包含相同的逻辑来确定所有这些设置的值。

    • ViewModel并没有明确展示应用程序工作流的概念。通常认为它会将控制权返回给调用视图。

    • 简单说,MVVM模式是利用框架(如WPF/SL)少写代码的PresentationModel的特例,这是Josh Smith所说的(参见http://msdn.microsoft.com/en-us/magazine/dd419663.aspx)。


    你能讲一下在不同的框架(如ASP.NET MVC,WPF和SL)中使用了哪些设计模式吗? - Jonas
    我绝对不认为自己了解所有的框架。你提到了.NET框架:ASP.NET MVC,带有“Views”和“Controllers”,非常遵循MVC(Ruby on Rails也应该如此);WPF/SL非常遵循MVVM,具有“XAML”UI组件和C#代码。对我来说,Caliburn.Micro在其ViewModel-first方法中更接近MVVM。即使被称为MV*,AngularJS对我来说也是一个相当好的MVVM示例,前提是视图不包含太多代码。 - superjos
    趁机插入链接到Jeremy Miller的文章,Build Your Own CAB Series,因为提到它们的答案对一些用户是隐藏的。 - superjos

    54

    Martin Fowler在UI设计模式页面上介绍了MVC、MVP等模式。 http://martinfowler.com/eaaDev/uiArchs.html

    控制器(Controller)主要用于控制UI,例如处理由UI触发的事件并进行适当的处理。

    展示器(Presenter)则相对被动,只是通过UI显示数据,由UI自己来处理事件,或者委托展示器到服务或命令。

    视图模型(ViewModel)是Presenter的一个具体实例,专门用于WPF/Silverlight绑定。

    演示模型(Presentation Model)是可以直接由视图呈现的模型,例如如果您的模型实现了INotifyPropertyChanged以进行数据绑定,则它们将成为Presentation Models。


    7
    它们之间的区别在于视图中有多少代码。选择它们实际上是选择应用程序技术,例如WFP、WinForms、ASP MVC(2)等。将逻辑与表示分离的基本思想是相同的。 这里 是一篇非常好的关于这三个模式的文章。

    编辑:

    另外一篇文章 - 比较。


    我看过很多关于这个主题的文章,但没有看到这篇。它看起来非常完整,谢谢。然而,我想提一下,唯一与技术相关的模式是MVVM,即使在Flex中也可以完全相同地实现。 - Nicholas

    6

    我的观点是,MVP、MVVC、MVC和Presentation Model之间没有真正的概念上的区别。虽然有一些细节上的差异,但最终,它们都可以被视为一个模型-视图-控制器设置。额外的命名只会带来混淆,我认为采用可以允许在描述控制器时具有一定余地的术语会更好。


    3
    你的意见是什么?我认为OP要求回答问题而非意见。此外,显然存在差异。在我看来,这个回答很糟糕。 - Tower
    18
    @Tower 哈哈,我是那个问问题的聪明人。 - Nicholas
    5
    这是无价的。 - dcow
    4
    然而,我认为这不是表达你的观点的地方,那不是一个答案。如果有的话,它应该作为问题的一部分提出(虽然它不是问题本身,但至少提供了某种背景/上下文)。 - skyking

    2
    重要的区别之一在于MVP和MVVM,VM可以与多个视图一起使用,而MVP通常是Presenter和View之间的1-1关系,并具有强制执行其方法的合同接口。Android在很大程度上将MVVM与ViewModel组件结合起来,该组件建立在保留片段的基础上。这是架构的选择模式,非常适合任何应用程序。

    1

    至少在 .Net 中,MVP 被用作设计模式。通常与 Windows Forms 应用程序或经典的 ASP.Net 一起使用。而 MVC 和 MVVC 则通常与 ASP MVC 一起使用,后者使用了与普通 ASP.Net 相当不同的架构。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接