活动巴士评论 [英] Event bus review

查看:87
本文介绍了活动巴士评论的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在开始使用 GWT 并学习 Event bus 概念。我觉得这个解决方案非常复杂。所以我试图通过自己编写原型来简化它,以查看所有问题。

首先,我会写关于我对事件总线的理解(这可能是完全错误的)。
我们有类似的事件

  public class FooEvent extends GwtEvent< FooHandler> {
public static Type< FooHandler> TYPE = new Type< FooHandler>(); //作为事件类型integer ID

// for .. hm ..可能在事件总线中有一些内部使用
@Override public Type< FooHandler> getAssociatedType(){
return TYPE;
}

//用于处理
@Override protected void dispatch(FooHandler handler){
handler.someMethod(this);
}
}

处理程序界面,

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

用法

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

就是这样。

  //替换为GwtEvent 
interface UniGwtEvent {
}

//比事件非常简单
public class FooEvent extends UniGwtEvent {
}
//替换GwtEventHandler。你不应该为每个事件创建特殊的处理程序类!
public interface UniEventHandler< T扩展UniGwtEvent> {
void handle(T event);
}
//事件总线原型(伪代码)
class UniEventBus {
// map。键从课堂上得到。据我所知,从GWT 1.5中可以看到http://code.google.com/p/google-web-toolkit/issues/detail?id=370
public< T extends UniGwtEvent> void addListener(Class< T> event,UniEventHandler< T>处理程序){
map.put(event.getName(),handler);
}
public void fireEvent(UniGwtEvent event){
if(map.contains(event.getClass()。getName())){$ b $ map.get(event)。处理(事件);
}
}
}

用法

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

我认为这个解决方案好得多,因为您不应该使不必要的 Type 操作并为每个事件创建Handler类。我只看到一个缺点 - 你应该在处理程序创建时指定泛型类型。但是我认为还有很多其他的缺点或者问题使得这个解决方案变得不可能。它们是什么?

解决方案

使用您的实现没有明显的优势。在我看来,你和GWT的 EventBus 之间有两点不同:


  1. <使用字符串而不是键入对象将事件处理程序绑定到事件类型。这不是一个有意义的区别 - 在应用程序中使用更多类型并没有任何损失,我怀疑在运行时, Strings 将使用比类型。


  2. 直接将事件分派给相应的处理程序,而不是委派给事件类型。我更喜欢GWT的方法,因为它为事件发送提供了灵活性。例如,有人可能希望处理程序实现根据事件的上下文调用的两种不同的方法。以下面的(不重要的)例子:

      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);



    code
    $ b在这种情况下委派调度到该事件允许我们采取必须为每个处理程序执行的操作(确定事件是否包含id或名称),而不要求在每个单独的事件处理程序中执行测试。

我推荐使用GWT的 EventBus 实现 - 它的工作原理和测试。


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?

解决方案

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.

这篇关于活动巴士评论的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆