5

特定のイベントの処理とデータの生成に基づくシステムを開発しようとしています。各イベントには(おそらく)いくつかの異なるフィールドが含まれ、各リスナーはそれらのいくつかを処理します。私は次の2つのアプローチを念頭に置いています

  1. イベント生成クラス内で、複数のイベントリスナーを登録します。各リスナーは、イベントの特定のフィールドの1つの特定の値をリッスンします。たとえば、次のようになります。

    public class MicroListener implements Listener {
    
    public void processEvent(Event e){
        if(e.getName().equals(registeredName)) { ... }
    }
    

処理はオブジェクト自体の中で行われ、イベントの集中処理はなく、各オブジェクトが情報を処理できるようにするため、これは魅力的です。不利な点は、おそらく致命的ですが、各イベント(数十万のうち)をすべてのリスナーにブロードキャストする必要があるという事実ですが、実際にはごく一部しかブロードキャストされません。それはおそらく長期的には素晴らしいパフォーマンスヒットを生み出すでしょう...

  1. 一元化されたリスナー。すべてのイベントをリッスンして処理し、対応するイベントプロセッサに処理を委任します。次に例を示します。

     public class CentralListener implements Listener {
    
        Map<String, Processor> processorsByName;
    
        public void processEvent(Event e){
            processorsByName.get(e.getName()).process(e);
        }
    }
    

これは高速ですが、イベントの他の部分(イベントIDなどをチェックするプロセッサなど)に対して個別のマップまたはプロセッサのコレクションが必要になります。これは、アプローチ1には当てはまりません。これは、単に別のリスナーのセットを生成して登録するためです。イベント生成クラスでそれらを。

あなたたちはこれらのどれについてどう思いますか?それらは理にかなっていますか、それともまったく異なるsthについてアドバイスしますか?

4

2 に答える 2

4

これは一般的な設計上の決定であり、すべての(またはほとんどの)ケースに正しい一般的な答えはないと思います。どちらのアプローチでもさまざまなトレードオフをリストできますが、それらはおそらく明らかです。大まかに言えば、パフォーマンスへの影響の可能性を検討する前に、概念モデルに最適な(そして無関係なクラスの混乱を引き起こさない)設計を優先します。

パフォーマンスが最大の懸念事項である場合は、整数のイベントIDで大きなスイッチ/ケースブロックの切り替えを使用する集中型コントローラーがおそらく最速です。...また、時間の経過とともに柔軟性/保守性が最も低くなります。

GuavaプロジェクトのEventBusを確認することをお勧めします。アノテーションを使用してイベントリスナーを登録し、このタイプのイベントブロードキャスト/サブスクライブに非常にクリーンなAPIを提供します。イベントサブスクライバーは、メソッドシグネチャで宣言するイベントのタイプに応じて通知されます。それは非常に滑らかで、多くの定型文を節約します。何千ものイベントタイプにどれだけ拡張できるかはわかりませんが、いくつかの同様のライブラリとは異なり、イベントバスはグローバルではありません。必要に応じて、さまざまなイベントバスインスタンスを作成して、イベント処理を分離できます。

于 2012-11-14T22:21:29.053 に答える
0

かなり大規模で (潜在的に) 複雑な何かの始まりにいるようです。あなたが言及した2つの命令型のアプローチを使用する前に、おそらくイベントベースのプログラミングを詳しく調べます。アイデアはリスナーを使用する場合とほとんど同じですが、非同期でのみ実装されるため、イベントリスナーは、アクションを要求されたときにのみ動作する独自の小さなスレッドにすることができます。

ここで適用できるかどうかはわかりませんが、さまざまなリスナーに伝播する必要があるさまざまなイベントタイプがあると仮定しましょう。オブザーバーを 1 つの巨大なヒープに格納する代わりに、オブザーバーが登録できるイベントの種類ごとにリスナーを作成してみませんか? イベントを生成するいくつかのコアコンポーネントがある場合、それらはリスナーでそれらを送信でき、再びオブザーバーに送信されます。

私の目には、主な利点は、世話をする前に責任が (サブ) リスナーに委任されることです。プログラマーを本当に助けることができる大規模な環境では、パフォーマンスのボトルネックを防ぎます。これはリアクターパターンとも呼ばれていると思います。

インスピレーションを探しているなら、akka フレームワークを見てみてください。これは、効率的な分散イベント プログラミング用に設計されています。

于 2012-11-14T22:40:45.077 に答える