Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVP Communication between presenters?

Tags:

mvp

winforms

I have a question about how to handle communication between presenters when using MVP. Say I have two MVP-triads. One is a list of products (Triad A) and the other is some general information about the currently selected product (Triad B).

How do I tell Presenter B that that it needs to update because the selected product has changed by A? I can of course think of ways to do this, but I was wondering if there is a general convention for how to handle this.

Thanks in advance for any ideas!

like image 354
user1277327 Avatar asked Mar 18 '12 19:03

user1277327


3 Answers

The pattern itself doesn't really prescribe how to handle this.

My own preference is a message/event hub where presenters can register interest in certain events. It prevents complex dependency trees and keeps the presenters testable.

For example:

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 would keep a list of subscribers to invoke for each event type.

You retain your testability - simply call on HandleProductChanged to see how PresenterB would respond to a new product selection.

The only disadvantage (as with any pattern) is you introduce a level of indirection. If PresenterA directly invoked PresenterB, or PresenterB listened to an event on PresenterA, it is immediately obvious what's going to happen.

In this approach, you would have the extra step seeing EventType.ProductChanged, and then finding which Presenters registered an interest in that event.

In my own experience, that single level of indirection is well worth modularity you get.

like image 180
Steven P Avatar answered Nov 10 '22 20:11

Steven P


Personally i disagree the way many people choose event bus to solve this kind of problems

It's hard for me to imagine a case when two presenters need to communicate each other, can you provide a real case?

In my opinion if two presenters need to communicate each other then you should merge these two in just one single presenter. Remember that also communication of models object between two use cases is business logic so maybe the scope of the presenter is bigger than you thought initially.

Consider also that if you use collaborators in the right way then you don't need communication between presenters. Data should be provided by collaborators.

like image 3
Tommaso Resti Avatar answered Nov 10 '22 18:11

Tommaso Resti


I'd like to add my point of view, coming with a mobile development background.

It seems to me that you are working with a typical Master-Detail scenario. What I would suggest is that despite the fact those containers A and B have their own presenters, because obviously they may have their own implementation scopes that needs to be handled in a clean way, they shouldn't directly talk to each other. They may live without each other. However if there is a way to present them at the same time - it would be done through a bigger container that handles them. And this is a key to your problem.

Declare interfaces that inform about the container A/B changes. Implement them within bigger container (let's call it host) and create a listener that will represent those interfaces to bind the communication.

Whenever there is a change in container A it informs host through interface, host passes the event to it's own presenter which can run a bigger scope operation like storing the state or sending analytic event to backend and finally it tells host to update the detail where the container B is given the data for update.

The solution with events is probably very tempting to use, I've done it myself many times, but it comes with a price. If you misuse it you'll just add to technical debt. I would suggest using this mechanism for situations where the "event" is not necessarily bound to any particular handling scenario, but may become a point of interest of other modules that live within your project.

like image 1
Kostek Avatar answered Nov 10 '22 18:11

Kostek