Latest Updates

MVP: Event Bus pattern instead of Listener

This question is more towards paradigm. Why is that we don't use Event Bus instead of listeners in an MVP environment? Typically, the "P" part has a dependency injection of view and model references. Sure this has the advantage of showing an explicit contract between the view and model via presenter, which is more readable.

However, wouldn't it be a cleaner approach to have the presenter listen to events from views and events carry the view payload (eg: JSON representation)? The same is the case with the presenter talking back to the viewer. The viewer will listen for events from the presenter. The major advantage is, we don't have to write interfaces for each contract between view and presenter. If you look at the code you will see that the presenter is getting exposed to view details like Text Fields, which I believe is increasing the coupling between the view and presenter. Say, if I'm replacing front-end JavaFx instead of Vaadin, I will have to alter the presenter as well.

You can use this in your build script in the build phase, use in Eclipse without a build script is just a use case. The policy of when to run is left to your creativityThis class is an example from a live project. Here we have different types of events ie I don't create event classes for different cases. Eg: LoginViewEvent, DashBoardEvent etc which I believe is a maintenance pain.

public class UrayEvent { public static enum EventType { SESSION_SELECTED(1), DOCUMENT_SELECTED(2), DOCUMENT_EDIT_COMPLETE(3), DOCUMENT_EDIT_CANCELED(4), SHOW_SESSION_TABLES(5), SHOW_SESSION_DOCUMENTS(6), SHOW_SESSION_COLLABORATORS(7), USER_REQUESTED_REFRESH(8), AUTO_REFRESH(9), TABLE_SELECTED(10), DETACHED(11), SCHEDULER_NAVIGATION(12), JIRA_USER_SELECTED(13), DOCUMENT_SAVE_SUCCESS(14), DOCUMENT_SAVE_FAILURE(14); private final int value; private EventType(int value) { this.value = value; } public int getValue() { return value; } } public static class Event { private final EventType type; private final Object payload; public Event(EventType type, Object eventPayload) { this.type = type; this.payload = eventPayload; } public EventType getEventType() { return type; } public Object getEventPayload() { return payload; } } }


Simple enough, the view sends the event DOCUMENT_EDIT_COMPLETE. The presenter layer handles this event. I found this way, a better way to decouple views from the presenter.

@Subscribe public void handle(UrayEvent.Event event) { switch (event.getEventType()) { case DOCUMENT_EDIT_COMPLETE: // event payload contains document model data // like document id etc saveDocument(event.getEventPayload); break; default: break; } }

Advantage
• Less boilerplate code,
• For n-views, we don't need n-interfaces
• A new event means adding an event element to an enum and updating respective subscribe methods handling this event.

Disadvantage
• Memory leak if we forget to unregister from the event bus (faced it plenty of times)

Questions
1) This approach means, there would larger set of enum elements as the application grows. Is this approach an anti-pattern?
2) As we saw it uses Event Bus extensively are there any drawbacks to using a bus system instead of an interface-listener pattern?
Wanted your valuable suggestion in this regard. The main issue is, if I blindly apply this pattern extensively across the project I shouldn't regret doing so, what would be a possible pitfall in this approach?