演示者之间的MVP沟通?

时间:2012-03-18 19:32:10

标签: winforms mvp

我有一个关于如何在使用MVP时处理演示者之间的通信的问题。说我有两个MVP三合一。一个是产品清单(Triad A),另一个是关于当前所选产品的一般信息(Triad B)。

如何告知Presenter B它需要更新,因为所选产品已被A更改?我当然可以想办法做到这一点,但我想知道是否有一个如何处理这个问题的一般惯例。

提前感谢任何想法!

3 个答案:

答案 0 :(得分:13)

模式本身并没有真正规定如何处理这个问题。

我自己的偏好是一个消息/事件中心,演示者可以在其中注册对某些事件的兴趣。它可以防止复杂的依赖树,并使演示者可以测试。

例如:

class PresenterA
{
   void HandleProductSelectionChanged(int productId)
   {
      EventHub.Publish(EventType.ProductChanged, productId);
   }
}

class PresenterB
{
    void PresenterB
    {
       EventHub.Register(EventType.ProductChanged, HandleProductChanged);
    }

    public void HandleProductChanged(object state)
    {
       var productId = (int)state;
       var productDetails = LoadProductDetails(productId);
       view.DisplayProductDetails(productDetails);
    }
}

EventHub将保留一个订阅者列表,以便为每种事件类型调用。

您保留了可测试性 - 只需致电HandleProductChanged,了解PresenterB如何响应新产品选择。

唯一的缺点(与任何模式一样)是引入一个间接级别。如果PresenterA直接调用了PresenterB,或者PresenterB在PresenterA上收听了一个事件,那么很明显会发生什么。

在这种方法中,您将看到EventType.ProductChanged的额外步骤,然后找到哪些Presenters注册了对该事件的兴趣。

根据我自己的经验,单一级别的间接是值得的模块化。

答案 1 :(得分:1)

我个人不同意许多人选择事件总线来解决这类问题的方式

我很难想象一个案例,当两位主持人需要互相沟通时,你能提供一个真实的案例吗?

在我看来,如果两位演示者需要相互沟通,那么您应该只在一位演示者中合并这两者。请记住,两个用例之间的模型对象的通信也是业务逻辑,因此演示者的范围可能比您最初想象的要大。

另请注意,如果您以正确的方式使用协作者,则不需要演示者之间的通信。数据应由合作者提供。

答案 2 :(得分:0)

我想添加自己的观点,并附带移动开发背景。

在我看来,您正在使用典型的主从方案。我的建议是,尽管这些容器A和B都有自己的演示者,因为显然它们可能有自己的实现范围,需要以一种干净的方式进行处理,所以它们不应直接相互交谈。他们可能没有彼此生活。但是,如果有一种方法可以同时显示它们,则可以通过一个更大的容器来处理它们。这是解决问题的关键。

声明用于通知有关容器A / B更改的接口。在更大的容器(将其称为主机)中实现它们,并创建一个侦听器,该侦听器将代表那些接口来绑定通信。

只要容器A发生变化,它都会通过接口通知主机,主机将事件传递给它自己的演示者,该演示者可以运行更大的作用域操作,例如存储状态或将分析事件发送到后端,最后告诉主机更新从站,容器B被提供了要更新的数据。

带有事件的解决方案可能很吸引人,我自己做过很多次,但是要付出代价。如果滥用它,只会增加技术债务。我建议在“事件”不一定绑定到任何特定处理方案的情况下使用这种机制,但是可能会成为项目中其他模块的兴趣点。