2009-01-09 40 views
12

我有一些乐趣,试图让我的头在一些MVP stuf,因为它涉及到用户控件。我正在使用.NET WinForms(或与之相近的东西)和Supervising Controller模式(嗯,我想我是:)。MVP和UserControls和调用

用户控件本身是MVP应用程序的一部分(其视图和关联的Presenter等)。演示者始终首先启动,然后启动模型然后查看视图。该视图建立其用户界面,其中的一部分将是新的UC,这是视图。

现在,(表单)演示者需要了解UC Presenter,但我认为它不知道视图是如何组成的。举例来说,Presenter并不知道UC是表单控件集合的一部分,也不应该。

此外,设计经验不应改变; IOW View(窗体)的开发者应该能够从工具箱中选择一个用户控件并将其放在窗体上。

所以,在我的问题。首先,我的假设是否正确?有点误导?弄乱? WTF你在想什么?

其次,是否有正确的(足够?)使窗体视图调用UC视图,并且窗体Presenter调用UC Presenter并且有一些机制来告诉UC View它的Presenter是什么?这打破了我的“演示者第一”规则,但我不知道该怎么做。

任何其他的想法,建议,评论欣然接受。

- nwahmaet

回答

12

演示者应该被认为是表示层中的“自治状态”。这意味着它有责任确保视图对模型状态的呈现是同步的。我之所以提出这个问题,是因为MVP的“模式”经常在教条式的观点0123中如何分开。似乎这是Martin Fowler决定尝试clarify the terminology around the MVP模式的原因之一。

我最喜欢的MVP的味道是passive view,所以我的答案是基于此。

我使用被动视图模式经常实现复合用户控件和窗体。基本上有3种不同的配置:

  1. 层次结构中所有用户控件的一个主持人。使用界面展平视图。
  2. 复合树中每个用户控件的一个主持人。每位家长演示者负责实例化并初始化其小孩演示者。用户控件是在设计时创建的,并且能够在没有演示者的情况下运行(没有演示文稿行为)
  3. 复合树中每个用户控件的一个演示者。所有的演讲者都是通过更高层次的控制器类来松散耦合的。控制器类负责构建演示者,连线并协调他们的事件。

虽然这是对我来说最后一招(因为它的复杂性)的解决方案,我认为最后的选择是您正在寻找的解决方案。

0

您的问题是普遍认为多种方案可以适用。

在这种情况下,我的猜测是你应该看Observer Pattern。

你有一个接口,任何使用该视图的实现。然后,它会在应用程序使用这些接口的集合进行初始化时注册自身。任何需要更新该视图的命令都会遍历集合,通知每个视图都应该更新。

与典型示例不同,视图将是用户控件。您可以灵活地使任何UI元素都能实现该界面,因此除了用户控件之外,您还可以使用对话框,完整表单等。

最后请记住,用户控件不是视图,而是视图的实现。无论您采用什么方案,您都可以定义视图的深度,并让用户控件实现该界面。

4

我在一个应用程序中工作了几个月,一直在解决这个问题。我最近得出的结论是,在很多情况下,不可能在窗口和用户控制级别应用MVP模式,也不能“破坏”模式。

我的想法是,用户控件是视图实现的一部分,并且演示者不应该知道视图实现内部发生了什么,这意味着窗口级别的演示者通过扩展应该不知道用户控制的主持人,因此它们之间不应该有任何沟通,包括前者对后者的实例化。可能会认为用户控件的演示者是窗口视图实现的一部分,因此窗口视图可能会实例化用户控件演示者。但它不能注入演示者需要的模型类,因为视图不应该意识到它们。

我认为我得出的结论是,所有用户控件都是特定于视图实现的,因此应该完全包含在较大模式的视图中。因此,他们不必拥有自己的演示者......至少不会与控制实施本身捆绑在一起。相反,它们应该由父窗口的演示者通过视图界面上公开的传递字段间接操纵。简而言之,用户控件不是通过自己的接口暴露给演示者,而是通过其父视图实现的通用传递接口。称此为“局部视图界面”。

然后,您的演示者可以包含可重用的子演示者类的实例,该类只能与此部分视图界面和模型的相关部分一起使用。这将允许您避免重写每次需要使用控件时从模型进行翻译的演示者代码,并且阻止窗口视图需要了解模型,以便将信息传递给控件的演示者。

这样做的效果是将用户控件作为模块从数据模型中进一步分离出来。如果将用户控件作为整体考虑为视图实现的一个元素,这是有道理的。作为一个可重用的单元,它是一个视图功能,并且它的任何部分都不应该绑定到您的数据模型。

+1

我同意所有的UC都是特定于实现的视图,但是也认为他们需要他们自己的演示者或模型,具体取决于UC的意图。导航面板可能具有Presenter逻辑而不是模型;一个邮政编码肯定查找需要一个模型。 – nwahmaet 2009-01-20 16:36:35

+1

我明白你的观点。我的感觉是,尽可能避免将自定义控件绑定到模型上。像这样绑定到您的应用程序体系结构中的控件我称之为“胖”控件。它们就像迷你的子窗户一样,在保持设计清洁/简单的同时很难处理。 – 2009-01-22 15:29:58