活动巴士审查

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

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

public class FooEvent extends GwtEvent { public static Type TYPE = new Type(); //as event type integer ID //for.. hm.. probably some inner use in Event Bus @Override public Type getAssociatedType() { return TYPE; } //for handling @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()); 

而已。 现在是我的原型。

 //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 { 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  void addListener(Class event, UniEventHandler handler){ map.put(event.getName(), handler); } public void fireEvent(UniGwtEvent event){ if(map.contains(event.getClass().getName())){ map.get(event).handle(event); } } } 

用法

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

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

使用您的实现没有明显的优势。 当我读到它时,你和GWT的EventBus之间有两个不同之EventBus

  1. 使用Strings而不是Type对象将事件处理程序绑定到事件类型。 这不是一个有意义的区别 – 在您的应用程序中有更多类型没有任何代价,我怀疑在运行时, Strings将使用比Types更多的资源。

  2. 直接将事件分派给适当的处理程序,而不是委托给事件类型。 我更喜欢GWT的方法,因为它提供了调度事件的灵活性。 例如,人们可能希望处理程序实现两种不同的方法,这些方法根据事件的上下文进行调用。 采取以下(微不足道的)示例:

     public class ExampleEvent extends GwtEvent { 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); } } } 

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

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

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

https://github.com/bennidi/mbassador

另一个选择是使用google guavas事件总线,但它缺少一些有用的function(这就是我实现自己的解决方案的原因)

编辑:我为一系列可用的事件总线实现创建了性能和function比较,包括Guava,MBassador等等。 结果非常有趣。 在这里查看http://codeblock.engio.net/?p=37