alkber
alkber

Reputation: 1436

MVP : : Event Bus pattern instead of Listener

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

However, wouldn't it be a cleaner approach to have presenter listen to events from views and events carry the view payload (eg: json representation). Same is the case with presenter talking back to the view. View will listen for events from presenter. 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 presenter is getting exposed to view details like Text Fields, which i believe is increasing coupling between view and presenter. Say, if i'm replacing front end JavaFx instead of Vaadin, i will have to alter presenter as well.

This class is an example from a live project. Here we have different types of events ie i don't create event class 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 send the event DOCUMENT_EDIT_COMPLETE .The presenter layer handles this event. I found this way, a better way to decouple views from 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

Disadvantage

Questions

1) This approach means, there would larger set enum elements as the application grow. Is this approach an anti pattern ?

2) As we saw it uses Event Bus extensively are there any drawbacks of using bus system instead of interface-listener pattern ?

Wanted your valuable suggestion on 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.

Upvotes: 4

Views: 2222

Answers (1)

iluwatar
iluwatar

Reputation: 1803

1) This approach means, there would larger set enum elements as the application grow. Is this approach an anti pattern ?

If there are many events you need many event identifiers. They can be simple ints or enums or Interfaces.

The mechanism you demonstrated is simple and works well with small applications. It has been proven many times over with multiple frameworks. Take for example Microsoft's Win32 API and MFC.

In some projects I have seen the event interceptors implemented with Annotations which provides an elegant way for handling the events. The previous time was in a project utilizing the Apache Wicket framework.

2) As we saw it uses Event Bus extensively are there any drawbacks of using bus system instead of interface-listener pattern ?

It is basically the same thing in a different package. In Java world it is de facto standard to use listener interfaces. Take for example Swing and Android.

The event bus approach is used in Facebook's Javascript based React framework. It is interesting to notice the similarity of Model-View-Presenter and Flux design patterns. Particularly the unidirectional data flow is highlighted in both architectures.

You mentioned the use case of replacing JavaFx with Vaadin as the UI framework. In my opinion, changing the UI framework so that you are able to reuse even some portions of it very rarely happens. I would not pay the price of added abstraction layers and complexity upfront just because the framework might change. Rather you should start with KISS and YAGNI principles. If you want to change the UI framework later, then you just implement the UI layer again from scratch.

Upvotes: 2

Related Questions