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!
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.