2009-06-10 13 views
5

"イベント"(キー入力、画面更新など)内で例外を処理する方法について、もう一度意見を出したいと思います。この場合、私はイベント送信者を制御できます。"イベント"内のJava例外処理

そこでモジュールは(それがリスナーインターフェースを実装し、イベントの送信者に対して登録された)イベントを処理するように設定されている:

public void DefaultSet (CardData oldDefault, CardData newDefault) 
{ 
} 

イベントの送信者は単に:だから

 for (Enumeration e = listeners.elements(); e.hasMoreElements();) 
     { 
      RetrieverListener thisListener = (RetrieverListener) e.nextElement(); 
      thisListener.DefaultSet(oldDefault, newDefault); 
     } 

受信機で問題が発生した場合:

  • 例外に対処する必要がありますか?再送信し、送信者に何も返すことはありませんか?時には、リスナーは正しくエラーを処理するための "コンテキスト"を持っていない、そうですか?

  • 例外をイベント送信モジュールに戻して、文書化された方法で処理することに悩まされていませんか?例えば"IOExceptionをスローするとリセットされます。"これは私が読んだjavadocsの非標準的なようです。

  • 何か問題が発生したときに例外を無視してログに記録すればよいですか?&何もできません。

答えて

6

Javaの規約では、リスナー・メソッドは例外をスローしません。明らかに、プログラミングエラーにより、リスナーはRuntimeExceptionをスローする可能性がありますが、プログラムのオブジェクトを不明な状態、矛盾した状態にする可能性があるため、イベントソースからリカバリできる方法はありません。

したがって、チェックされた例外をキャッチしてそれらからリカバリする(トランザクションをロールバックするなど)、またはそれらを他のオブジェクトに報告する必要があります。

public interface ErrorHandler { 
    public void errorOccurred(String whatIWasTryingToDo, Exception failure); 
} 

イベントリスナーが発生したエラーについてそののErrorHandlerを伝えます:私は、多くの場合のようになりますのErrorHandlerインターフェースを使用しています。

public class SomeClass implements SomeKindOfListener 
    private final ErrorHandler errorHandler; 
    ... other fields ... 

    public SomeClass(ErrorHandler errorHandler, ... other parameters ...) { 
     this.errorHandler = errorHandler; 
     ... 
    } 

    public void listenerCallback(SomeEvent e) { 
     try { 
      ... do something that might fail ... 
     } 
     catch (SomeKindOfException e) { 
      errorHandler.errorOccurred("trying to wiggle the widget", e); 
     } 
    }   
} 

私は、アプリケーションでその時点で理にかなってどのような方法で失敗を処理します。この実装でイベントリスナーを初期化します。ダイアログをポップアップしたり、ステータスバーに点滅しているエラーアイコンを表示したり、監査メッセージを記録したり、プロセスを中止したりすることができます。

+0

興味深いアーキテクチャと有用な答え、ありがとう!私の問題は、リスナーが常に物事を表示したり、ユーザーのフィードバックを提供したりすることではなく、イベントを使用して、例外を非常に強力にするトップダウンスタックアナロジーを歪ませることです(スタック内の適切なポイント、何かができる場所)。 とにかく、リスナーはエラーを処理しなければならないと思います。 –

+0

リスナーがエラーを処理できるようにシステムを設計する必要があります。例外は、スタックをリスナーに巻き戻します。リスナーは、例外にどのように対処するかを知ることができないもの、Swingイベントディスパッチスレッドで呼び出されたボタン、JMSプロバイダのメッセージ配信スレッドなどによって呼び出されています。例外に賢明に反応するために必要なすべてのコンテキストを与えることができる場所と時間にリスナーをインスタンス化する必要があります。 – Nat

1

ログに記録してユーザーにメッセージを送信する必要はありません。何かがうまくいかないと、データを破損したり、回復できない場合に誤った結果を与える可能性があります。アプリケーションを終了する必要があります。

0

通常の方法は、問題を無視することです。リスナーはチェックされていない例外をスローするべきではありません。

より良い方法は、RuntimeExceptionを捕まえてログに記録することです。これらは一般にプログラミングエラーを示します。画面上のウィジェットがNPEを投げた場合、残りのウィンドウがペイントを終了してはならない理由はありません。その後、ユーザーはデータを保存して再起動するか、問題を回避することができます。 Errorの場合、それは一般的に、OutOfMemeoryのような深刻な状況があり、捕まえてしまうだけでスラッシングが発生することを意味します。誰もこれをやっていない。

+0

"窓の残りの部分が絵を描くべきではない理由はありません" - 確かにあります。行方不明のウィジェットは非常に重要であり、ウィンドウの残りの部分は役に立たないかもしれません。実際、それは役に立たず、何かをしているように見えるかもしれません。これは、単にクラッシュするよりもユーザー体験が悪いことです。プログラマーが特定の状態を期待していない場合は、その状態がちょうど破壊されていると考える必要があります。 – cdhabecker