Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 事件总线回顾_Java_Gwt_Event Bus - Fatal编程技术网

Java 事件总线回顾

Java 事件总线回顾,java,gwt,event-bus,Java,Gwt,Event Bus,我现在从GWT开始学习事件总线概念。我觉得这个解决方案非常复杂。所以我试图通过自己编写原型来简化它,以了解所有问题 首先,我将写下我对事件总线的理解(这可能是完全错误的)。 我们有这样的活动 public class FooEvent extends GwtEvent<FooHandler> { public static Type<FooHandler> TYPE = new Type<FooHandler>(); //as event type i

我现在从GWT开始学习事件总线概念。我觉得这个解决方案非常复杂。所以我试图通过自己编写原型来简化它,以了解所有问题

首先,我将写下我对事件总线的理解(这可能是完全错误的)。 我们有这样的活动

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);
    }
}
用法

eventBus.addHandler(FooEvent.TYPE, new FooHandler() {
    @Override
    public void someMethod(FooEvent event) {
        //bla-bla
    }
});
eventBus.fireEvent(new FooEvent());
eventBus.addListener(FooEvent.class, new UniEventHandler<FooEvent>(){
    @Override
    public void handle(FooEvent event) {
        bla-bla
    }
});
eventBus.fireEvent(new FooEvent());
就这样。现在是我的原型

//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);
        }
    }
}
//替换了GwtEvent
接口UniGwtEvent{
}
//比这更简单
公共类FooEvent扩展UniGwtEvent{
}
//取代了格温坦德勒。您不应该为每个事件创建特殊的处理程序类!
公共接口UniEventHandler{
无效句柄(T事件);
}
//事件总线原型(伪代码)
类UniEventBus{
//map.keys是从类中获取的。据我所知,它可能来自GWT1.5,请参见http://code.google.com/p/google-web-toolkit/issues/detail?id=370 
public void addListener(类事件,UniEventHandler){
put(event.getName(),handler);
}
公共无效火灾事件(UniGwtEvent事件){
if(map.contains(event.getClass().getName())){
map.get(事件)、handle(事件);
}
}
}
用法

eventBus.addHandler(FooEvent.TYPE, new FooHandler() {
    @Override
    public void someMethod(FooEvent event) {
        //bla-bla
    }
});
eventBus.fireEvent(new FooEvent());
eventBus.addListener(FooEvent.class, new UniEventHandler<FooEvent>(){
    @Override
    public void handle(FooEvent event) {
        bla-bla
    }
});
eventBus.fireEvent(new FooEvent());
eventBus.addListener(FooEvent.class,新的UniEventHandler(){
@凌驾
公共无效句柄(FooEvent事件){
布拉布拉
}
});
fireEvent(新的FooEvent());

我认为这个解决方案要好得多,因为您不应该对每个事件进行不必要的
类型
操作和创建处理程序类。我只看到一个缺点——您应该在创建处理程序时指定泛型类型。但我认为还有许多其他的缺点或问题使得这个解决方案不可能实现。它们是什么?

使用您的实现没有明显的优势。正如我所读到的,您的和GWT的
EventBus
之间有两个区别:

  • 使用
    字符串
    而不是
    类型
    对象将事件处理程序绑定到事件类型。这并不是一个有意义的区别-在应用程序中使用更多类型不会带来任何损失,我怀疑在运行时,
    字符串
    将比
    类型
    使用略多的资源

  • 直接将事件分派给相应的处理程序,而不是委派给事件类型。我更喜欢GWT的方法,因为它提供了事件调度方式的灵活性。例如,您可能希望处理程序实现两个不同的方法,根据事件的上下文调用这两个方法。以以下(琐碎的)例子为例:

    公共类ExampleEvent扩展了GwtEvent{
    公共接口处理程序扩展了EventHandler{
    void-onExample(整数id);
    void onExample(字符串名称);
    }
    私有最终整数id;
    私有最终字符串名;
    公共示例事件(整数id){
    this.id=id;
    this.name=null;
    }
    公共示例事件(字符串名称){
    this.name=名称;
    this.id=null;
    }
    公共无效调度(处理程序){
    if(name!=null){
    handler.onExample(名称);
    }否则{
    handler.onExample(id);
    }
    }
    }
    
    在这种情况下,将分派委派给事件允许我们采取必须对每个处理程序执行的操作(确定事件是否包含id或名称),而无需在每个单独的事件处理程序中执行测试


  • 我建议使用GWT的
    EventBus
    实现—它可以工作,并且经过测试。

    还有其他的事件总线实现可以做得很好。我最近创建了一个非常高效的事件总线(Mbassador),我已经在生产中使用了一段时间了。它托管在github上,欢迎您查看

    另一个选择是使用GoogleGuavas事件总线,但它缺少一些有用的功能(这就是为什么我实现了自己的解决方案)

    编辑:我为一系列可用的事件总线实现(包括Guava、MBassador等)创建了性能和功能比较。结果很有趣。看看这里

    谢谢@Jason。当然,我将使用GWT的
    EventBus
    实现。我问这个问题只是为了澄清这些解决方案的“遗产”。1) 作为开发人员,我认为“我的”解决方案更可取,不应该在
    类型
    操作方面做出任何努力,我看不到真正的缺点。2) 有两种方法很好,我以前没有考虑过这一点。但你们应该把这种逻辑放在事件中吗?你知道这种方法有什么真正好的例子吗?我会在我的答案中加上一个例子。谢谢。只是在repo中添加了一些示例代码,以进一步说明其用法。我想,在不久的将来,我将发布一个与其他总线实现的速度比较。