2011-08-19 12 views
5

私はEclipse RCPベースのフレームワークを使用していますが、これは非効率なイベントモデルに悩まされています。具体的には、コントロールによって放出されるイベントはしばしば「カスケード」します。たとえば、コントロールはCOLOR_CHANGEDイベントを発行し、親コンポジットにイベントを兄弟コントロールに伝播させます。兄弟コントロールは、独自のイベントに応答して独自のイベントを発生させ、ソートの連鎖反応をもたらします。私は簡単なフォームをレンダリングするために100,000以上のイベントを上げるアプリをプロファイリングしました。率直に言って、どうやってスタックがあふれているのか分かりません。イベントが連鎖反応を引き起こしています

私はこの種のカスケード動作を防止または軽減するテクニックまたはデザインパターンを探しています。私はいくつかのアイデアを持っていましたが、これは新しい問題にはなりません。イベント指向設計のためにすでに「ベストプラクティス」があるはずです。

私のアイデア:新しいイベントがその原因に連鎖しているので、

  • イベントは、スタックトレースのように動作します。これにより、リスナーは自分自身から発生したイベントを無視できます。しかし、これは私のイベントモデルを非常に複雑にします(そして、標準SWTイベントをラップするのは面倒です)。実際にこの動作が必要な有効なユースケースがあります。
  • イベントを発生させるために中央の「イベントポンプ」が使用されます。最後のnミリ秒内にイベントが以前に発生したイベントと同じソースとペイロードを持っている場合、そのイベントは破棄されます。うまくいけばドーピング効果があり、出来事がカスケードするのを防ぐでしょう。明らかに、SWT/RCPイベントがどのように発生するかを制御することはできませんが、これは私の主な関心事ではありません。
  • イベントを入力する必要があります。これは一歩後退のようですが、細かい粒度のイベントがパフォーマンスに役立つと思います。たとえば、誰でも処理する汎用のEventではなく、ValidationFailedEventです(イベントの種類を判断するために状態を調べる必要があります)。

私の問題について読んでいただきありがとうございます。すべてのアドバイス/提案は大歓迎です。

EDIT:pablosaraivaのおかげで、私は約Chain-of-responsibility、今は、次のアイデアを持って読んで:

  • イベントは、trueに設定されている場合、伝播するイベントを防ぐことができますisHandledプロパティを公開します。これは、イベントのスコープが理解されているが、イベントが単一のコントロールで '処理'できない場合には役立ちません。
+1

あなたはChain of Responsibilityを見ましたか? – pablosaraiva

+0

@pablosaraiva:有望そうに見えましたが、「1対多数」のイベント、つまり多くのコントロールがイベントを受け取る必要がある場合、どのように役立つのか分かりません。 – hoipolloi

+0

あなたは「Eclipse RCPベースのフレームワーク_」と言います。これはSWTを意味するはずですが、これで残りの説明はできません。どのようなフレームワークを意味していますか? –

答えて

1

私はこれまで数多くの異なるアプローチで遊んできました。これを修正するためにできる基本的なことは、モデルが実際に変更された場合にのみイベントを放出させることです。これにより、モデル内のクラスごとにモデルが少し複雑になりましたが、このパラダイムが機能するように管理した唯一の方法です。

public void setColor(Color c) 
{ 
    setBackground(c); 
    notify(new ColorChangedEvent(this, c)); 
} 

例えば

'はsetChanged()' メソッドでこれをJavaサポートで

public void setColour(Color c) 
{ 
    if (!getBackground().equals(c)) 
    { 
     setBackground(c); 
     notify(new ColorChangedEvent(this, c)); 
    } 
} 

標準観測クラスなります。

これを実装するのは(IMHOは良くないが)やや簡単な方法は、通知を終了するまで聞き取りをオフにすることです。つまり、

private iAmNotifying; 
public void notify(Event e) 
{ 
    if (!iAmNotifying) 
    { 
     iAmNotifying = true; 
     doTheActualNotification(e); 
     iAmNotifying = false; 
    } 
} 

のようなルックスに通知される。しかし、これは粒度の面でいくつかの重大な欠点を持っている、と私は最初のアプローチとのより良い成功を収めてきました。

+0

両方の素晴らしい提案。私が想像することができる唯一の欠点は、イベントが非同期的に発生した場合に複雑になるかもしれない2番目のスニペットに関連しています。 – hoipolloi

関連する問題