Event bus review

限于喜欢 提交于 2019-12-09 07:08:37

问题


I'm starting with GWT and learning Event bus concepts now. I find this solution extremely complicated. So I tried to simplify it by writing prototype by myself to see all problems.

At first I will write about my understanding of event bus (that can be completely wrong). We have events like this

public class FooEvent extends GwtEvent<FooHandler> {
    public static Type<FooHandler> TYPE = new Type<FooHandler>(); //as event type integer ID

    //for.. hm.. probably some inner use in Event Bus
    @Override public Type<FooHandler> getAssociatedType() {
        return TYPE;
    }

    //for handling
    @Override protected void dispatch(FooHandler handler) {
        handler.someMethod(this);
    }
}

handler interface,

public interface FooHandler extends EventHandler {
    void someMethod(FooEvent event);
}

usage

eventBus.addHandler(FooEvent.TYPE, new FooHandler() {
    @Override
    public void someMethod(FooEvent event) {
        //bla-bla
    }
});
eventBus.fireEvent(new FooEvent());

Thats it. And now my prototype.

//replaced GwtEvent
interface UniGwtEvent { 
}

//than, event pretty simple
public class FooEvent extends UniGwtEvent  {
}
//replaced GwtEventHandler. You should not create special handler class per event!
public interface UniEventHandler<T extends UniGwtEvent> {
    void handle(T event);
}
//event bus prototype(in pseudocode)
class UniEventBus {
    //map. keys getted from class. as I understand, it's possible from GWT 1.5 see http://code.google.com/p/google-web-toolkit/issues/detail?id=370 
    public <T extends UniGwtEvent> void addListener(Class<T> event, UniEventHandler<T> handler){
        map.put(event.getName(), handler);
    }
    public void fireEvent(UniGwtEvent event){
        if(map.contains(event.getClass().getName())){
            map.get(event).handle(event);
        }
    }
}

usage

eventBus.addListener(FooEvent.class, new UniEventHandler<FooEvent>(){
    @Override
    public void handle(FooEvent event) {
        bla-bla
    }
});
eventBus.fireEvent(new FooEvent());

I think this solution is much better since you shouldn't make unnecessary Type manipulation and create Handler Class per event. I see only one disadvantage - you should specify generic type on handler creation. But I suppose there are many other disadvantages or ever issues that makes this solution impossible. What are they?


回答1:


There is no obvious advantage to using your implementation. As I read it there are two differences between yours and GWT's EventBus:

  1. Using Strings instead of Type objects to bind event handlers to event types. This is not a meaningful difference - there's no penalty to having more types in your application and I suspect that, at runtime, Strings will use slightly more resources than Types.

  2. Dispatching events to the appropriate handlers directly instead of delegating to the event type. I prefer GWT's approach here because it affords flexibility in how events are dispatched. One might, for example, want handlers to implement two different methods that are invoked depending on the context of the event. Take the following (trivial) example:

    public class ExampleEvent extends GwtEvent<ExampleEvent.Handler> {
      public interface Handler extends EventHandler {
        void onExample(Integer id);
        void onExample(String name);
      }
    
      private final Integer id;
      private final String name;
    
      public ExampleEvent(Integer id) {
        this.id = id;
        this.name = null;
      }
    
      public ExampleEvent(String name) {
        this.name = name;
        this.id = null;
      }
    
      public void dispatch(Handler handler) {
        if (name != null) {
          handler.onExample(name);
        } else {
          handler.onExample(id);
        }
      }
    }
    

    In this case delegating dispatch to the event allows us to take an action that must be performed for every handler (determining whether the event contains an id or a name) without requiring that the test be performed in every individual event handler.

I recommend using GWT's EventBus implementation - it works and it is tested.




回答2:


There are other event bus implementations out there that will do a good job. I recently created a very efficient event bus (Mbassador) that I have been using in production for a while now. It's hosted on github and you are invited to take a look.

https://github.com/bennidi/mbassador

Another option would be to use google guavas event bus but it lacks some useful features (which is why I implemented my own solution)

EDIT: I created a performance and feature comparison for a selection of available event bus implementations including Guava, MBassador and some more. The results are quite interesting. Check it out here http://codeblock.engio.net/?p=37



来源:https://stackoverflow.com/questions/5193386/event-bus-review

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!