为什么状态不能成为MVP模式中Presenter的一部分?

9
我阅读了http://www.codeproject.com/KB/architecture/MVC_MVP_MVVM_design.aspx,其中提到:
尽管MVC和MVP非常强大,但它们都存在问题。其中一个问题是View状态的持久性。例如,如果Model作为一个领域对象不知道UI的任何信息,而View没有实现任何业务逻辑,那么我们在哪里存储View元素(如所选项目)的状态呢?Fowler提出了一种解决方案——Presentation Model模式。
我想知道Presenter为什么不能保存View状态?它已经包含了所有View逻辑。
据我所知,在MVC和MVP中,状态保存在View中。在PM和MVVM中,状态保存在Presentation Model中。为什么Presenter在这种特殊情况下不能遵循PM并包含视图的状态?
这里有另一篇文章指出Presenter不保存View状态,而是由View保存:http://www.codeproject.com/KB/aspnet/ArchitectureComparison.aspx

它打破了模式。WPF的强大是通过DataTemplate来实现的。视图“查看”数据类型并“充气”到其定义的DataTemplate中。MVP还允许“视图优先”方法;这使得更容易从定义的ViewModel更改View。例如:如果您的ViewModel公开一个IList<Customer> Customers,您可以轻松更改View而不是更改View和Controller(MVC)。 - Jake Berger
我不同意“不应该存储视图元素的状态,比如选中的项目”的说法。许多属性可以成为模型的一部分,以便保留视图状态,例如一个“IsSelected”属性,而不会破坏设计模式。 - Todd
在第一篇文章的摘要中,你提到作者说:“MVP将更多的工作委托给View并移除了Controller。它引入了Presenter类来封装View的状态和命令。”因此,这篇文章似乎存在矛盾之处。 - Marijn
@Marijn 是的,我两天前才注意到这一点。我不确定该怎么想。你认为状态应该在Presenter中吗? - Tower
在干净的MVP中,你不会这样做;我更新了我的答案,试图更清楚地反映这一点。 - Marijn
@tod -- 一个更好的例子可能是在滚动列表中的位置。每次视图呈现时都不想跳到列表顶部,但同样地,也不想使用类似“当前列表顶部”的属性来污染您的模型。 - James Anderson
1个回答

10
当你说MVP中视图存储视图状态时,我认为你是完全正确的:这只是MVP中“关注点分离”的方式。在“干净的MVP”中,视图状态保存在视图中而不是在展示者中。展示者可以通过视图接口提供的方法查询其状态。
将状态保留在展示者中将使您的展示者成为演示模型和展示者之间的混合体。要实用主义,如果您发现自己有时在展示者中保留某些视图状态,请不要重新构建完整的应用程序。
只需了解使用PM或MVP模式的一般动机即可。
在Fowler的eeaDev网站上的Presentation Model文章中,他说:
Presentation Model是一种从视图中提取表示行为的模式。因此,它是监督控制器和被动视图的替代方案。它对于允许您在没有UI的情况下进行测试、支持某种形式的多个视图以及分离关注点可能使开发用户界面更容易很有用。
Fowler继续说:
与被动视图和监督控制器相比,Presentation Model允许您编写完全独立于用于显示的视图的逻辑。您也不需要依赖视图来存储状态。缺点是您需要一种演示模型和视图之间的同步机制。
我不同意你在问题中引用的那句话:
MVP的问题之一是View状态的持久性。
这不是问题,而是选择。在我看来,Fowler没有将“视图状态的持久性”作为选择Supervising ControllerPassive View时使用演示模型的动机进行提及。
我不确定Fowler所说的“存储状态”是否指的是“跨应用程序生命周期”的持久性。但无论如何,问题在于它是一种有利有弊的选择:当您使用演示模型而非MVP时,您可获得更好的视图状态可测试性、视图与(存储)视图状态的独立性、以及“程序员”可以创建PM,“UI设计师”可以独立处理视图。
代价是需要同步视图和演示模型。请注意,后者的“代价”现今可能比Fowler写作时(2006年)小一些,因为现代UI同步技术(例如.NET的数据绑定)的出现。

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