Обзор событий на автобусе - PullRequest
2 голосов
/ 04 марта 2011

Я начинаю с 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 манипуляций и создавать класс обработчиков для каждого события. Я вижу только один недостаток - вы должны указать универсальный тип при создании обработчика. Но я полагаю, что есть много других недостатков или проблем, которые делают это решение невозможным. Что они?

Ответы [ 2 ]

4 голосов
/ 04 марта 2011

Нет очевидного преимущества в использовании вашей реализации.Насколько я понимаю, между вами и GWT EventBus есть два различия:

  1. Использование Strings вместо Type объектов для привязки обработчиков событий к типам событий.Это не имеет существенного значения - штраф за использование большего количества типов в вашем приложении отсутствует, и я подозреваю, что во время выполнения Strings будет использовать немного больше ресурсов, чем Types.

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

    В этом случае делегирование отправки события позволяет нам выполнить действие, которое должно быть выполнено для каждого обработчика (определение, содержит ли событие идентификатор или имя)не требуя выполнения теста в каждом отдельном обработчике событий.

Я рекомендую использовать реализацию GWT EventBus - она ​​работает и тестируется.

3 голосов
/ 23 октября 2012

Существуют и другие реализации шины событий, которые будут хорошо работать.Недавно я создал очень эффективную шину событий (Mb Ambassador), которую уже некоторое время использую в производстве.Он размещен на github, и вам предлагается взглянуть.

https://github.com/bennidi/mbassador

Другой вариант - использовать шину событий google guavas, но в ней отсутствуют некоторые полезные функции (именно поэтому я реализовалмое собственное решение)

РЕДАКТИРОВАТЬ: я создал сравнение производительности и возможностей для выбора доступных реализаций шины событий, включая Guava, MB Ambassador и некоторые другие.Результаты довольно интересные.Проверьте это здесь http://codeblock.engio.net/?p=37

...