【问题标题】:MVP and multiple User ControlsMVP 和多个用户控件
【发布时间】:2010-10-21 15:37:15
【问题描述】:

我正在尝试使用 MVP 模式,但遇到了设计问题。我正在开发一个包含多个 UserControl 的应用程序。 UserControls 本身彼此无关,仅代表实际模型的一个子集。根据我的阅读,人们倾向于说每个视图应该使用一个演示者。这似乎有道理,但如果我有 30 个用户控件,我真的想要 30 个演示者吗?另一方面,如果我有 1 个 Presenter 和 1 个 View 代表整个“应用程序”视图,那么我将拥有臃肿的 View 和 Presenter 界面。然后每个视图都必须实现与它无关的方法。我的问题是,是否有更好的方法来处理多个用户控件,或者我应该为每个视图创建 1 个演示者?

【问题讨论】:

    标签: c# design-patterns oop user-controls mvp


    【解决方案1】:

    每个 View 不必实现相同的界面... 为什么不为每个控件定义界面,并为包含所有控件的整个屏幕设置一个 Presenter? Presenter 可以根据每个视图需要的接口定义事件“连接”每个视图上的事件,连接到 Presenter 上的适当事件处理程序(如果您正在执行 MVPC,则在控制器上)。您可能还需要另一个接口来表示所有视图都需要共同访问的 Presenter 功能......

    • 如果您正在执行 MVPC,则影响模型的视图事件将在控制器中“处理”,而仅影响视图其他部分的视图事件将在演示器上处理。

    【讨论】:

      【解决方案2】:

      将相关的代码分组到一个对象中会更有意义。因此,在这种情况下,如果视图是相关代码的特定分组,那么演示者也会模仿这些分组。为不同的视图设置一个“全局”演示者会将不相关的代码分组到一个对象中。它肯定也会使演示者的界面膨胀。查看single responsibility principle

      现在,您可以拥有一个 Presenter Manager 类,或许可以让您通过任一继承访问每个演示者接口 like the Interface Segregation Principle 状态(拥有一个实现许多演示者接口的全局具体演示者......哪种违反了单一责任)或聚合(每个接口都有单独的演示者和获取函数......因此全局接口将是获取函数)或两者的组合(全局演示者在某种程度上是一个适配器)。

      我认为最好的解决方案是拥有 30 位不同的演示者。

      【讨论】:

      • 这里的危险在于,多个视图可能会独立加载相同的数据实体。还是我错过了重点?
      • 如果您有需要由多个控件使用的共享数据,则应该有一个单独的层为它们提供该数据。最简单的可能是一些 datafetcher 对象(或多个对象),在创建时传递给每个控件的 Presenter,他们可以在需要时从中请求所需的数据。
      • @Chap 你能否展示一些代码来演示视图之间的共享上下文和通信
      【解决方案3】:

      您应该为每个控件做一个演示者,因为:

      • 这将使您能够专注于单元测试只处理该控件
      • 提高了可维护性,因为您不需要支持包含所有控件的演示逻辑联合的巨型演示器
      • 这将防止冗余在多个页面上具有相同控件的情况下
      • 通过在页面执行容器特定角色时让控件专注于其特定逻辑来提高 SRP

      通常提到与决策“presenter per control”相关的两个问题:

      • 共享上下文是一个问题,由于所有控件只是显示同一页面数据上下文的不同部分,这种情况可能看起来像一个有问题的用例,导致大量数据检索冗余每个控件中的代码。 这很容易通过依赖注入解决,其中页面(或控制器)执行单个数据检索,然后将数据上下文对象注入每个演示者\视图(通常实现一些启用该功能的接口)。 在 MV-VM 模式(Silverlight、WPF)的情况下,可以通过数据边界来实现相同的效果,其中页面将设置其 DataContext,然后在视图本身中使用它
      • 同一页面上的视图之间的通信是第二个问题,可以使用以下几种方法轻松解决:
      • 控件正在发布页面订阅的事件,然后直接调用其他控件中的适当方法(页面是所有控件的容器,这意味着它知道其所有成员)
      • 观察者设计模式
      • 事件聚合器模式

      在这些方法中的每一种中,控件都在彼此不知情的情况下相互通信

      【讨论】:

      • 能否请您展示一些代码来演示视图之间的共享上下文和通信
      【解决方案4】:

      老问题,但我要直言不讳,不得不不同意其他答案: 您不希望每个 UserControl 有一个演示者,就像您希望对每个 UserControl 进行单元测试一样 - 这将是对设计模式的盲目滥用。

      UserControl 不是视图。

      应用程序的每个逻辑区域都应该有一个演示者;如何分解每个控件 - 有多少控件,显示什么 - 完全是 组合 的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多