活动巴士回顾
我现在从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);
}
}
处理程序接口的事件,
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<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);
}
}
}
我认为
eventBus.addListener(FooEvent.class, new UniEventHandler<FooEvent>(){
@Override
public void handle(FooEvent event) {
bla-bla
}
});
eventBus.fireEvent(new FooEvent());
这个解决方案要好得多,因为您不应该进行不必要的 Type
操作并为每个事件创建处理程序类。我只看到一个缺点 - 您应该在创建处理程序时指定通用类型。但我认为还有许多其他缺点或问题使该解决方案变得不可能。这些是什么?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用您的实现没有明显的优势。据我了解,您的 EventBus 与 GWT 的 EventBus 之间有两个区别:
使用
Strings
而不是Type
对象将事件处理程序绑定到事件类型。这不是一个有意义的差异 - 在应用程序中拥有更多类型不会造成任何损失,而且我怀疑在运行时,Strings
将使用比Types
稍多的资源。 p>直接将事件分派到适当的处理程序,而不是委托给事件类型。我更喜欢 GWT 的方法,因为它为事件的分派方式提供了灵活性。例如,人们可能希望处理程序实现两种不同的方法,根据事件的上下文调用这两种方法。采取以下(简单)示例:
在这种情况下,将分派委托给事件允许我们采取必须为每个处理程序执行的操作(确定事件是否包含 ID 还是名称),而不需要在每个单独的事件处理程序中执行测试。< /p>
我建议使用 GWT 的
EventBus
实现 - 它有效并且经过测试。There is no obvious advantage to using your implementation. As I read it there are two differences between yours and GWT's
EventBus
:Using
Strings
instead ofType
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 thanTypes
.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:
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.还有其他的事件总线实现可以做得很好。我最近创建了一个非常高效的事件总线(Mbassador),我已经在生产中使用了一段时间了。它托管在 github 上,邀请您查看。
https://github.com/bennidi/mbassador
另一种选择是使用 google guavas 事件总线,但它缺乏一些有用的功能(这就是我实现自己的解决方案的原因)
编辑:我为一系列可用的事件总线实现(包括 Guava、MBassador 等)创建了性能和功能比较。结果非常有趣。在这里查看
http://codeblock.engio.net/?p=37
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