2

私は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不要な操作を行ったり、イベントごとに Handler クラスを作成したりしないため、このソリューションの方がはるかに優れていると思います。欠点は 1 つだけです。ハンドラーの作成時にジェネリック型を指定する必要があります。しかし、この解決策を不可能にする他の多くの欠点や問題があると思います。彼らは何ですか?

4

2 に答える 2

4

実装を使用することに明らかな利点はありません。私が読んだように、あなたとGWTの間には2つの違いがありますEventBus

  1. Stringsオブジェクトの代わりに使用Typeして、イベントハンドラーをイベントタイプにバインドします。これは意味のある違いではありません。アプリケーションに多くのタイプを含めることによるペナルティはなく、実行時に、Stringsよりもわずかに多くのリソースを使用すると思われますTypes

  2. イベントタイプに委任するのではなく、適切なハンドラーにイベントを直接ディスパッチします。ここでのGWTのアプローチは、イベントのディスパッチ方法に柔軟性をもたらすため、私は好みます。たとえば、イベントのコンテキストに応じて呼び出される2つの異なるメソッドをハンドラーに実装させたい場合があります。次の(簡単な)例を見てください。

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

    この場合、ディスパッチをイベントに委任すると、個々のイベントハンドラーごとにテストを実行しなくても、ハンドラーごとに実行する必要のあるアクション(イベントにIDまたは名前が含まれるかどうかの判別)を実行できます。

GWTのEventBus実装を使用することをお勧めします-それは機能し、テストされています。

于 2011-03-04T18:34:51.950 に答える
3

うまく機能するイベント バスの実装は他にもあります。私は最近、非常に効率的なイベント バス (Mbassador) を作成しました。これは、しばらく本番環境で使用しています。github でホストされているので、ぜひご覧ください。

https://github.com/bennidi/mbassador

別のオプションは、Google guavas イベント バスを使用することですが、いくつかの便利な機能が欠けています (これが、私が独自のソリューションを実装した理由です)。

編集: Guava、MBassador などを含む利用可能なイベント バス実装の選択のパフォーマンスと機能の比較を作成しました。結果は非常に興味深いものです。ここでチェックしてください http://codeblock.engio.net/?p=37

于 2012-10-23T08:43:31.967 に答える