オブジェクトのチェックと処理時にcontinueまたはChecked例外を使用する


3

"Document"オブジェクトのリストを処理しています。ドキュメントの処理を記録する前に、最初にいくつかのことを確認したいと思っています。たとえば、ドキュメントを参照するファイルが存在し、ドキュメント内に何かが存在するはずです。この例では2つの単純なチェックだけですが、文書を正常に処理するまでにはさらに8つのチェックがあると思います。

あなたの好みは?より読みやすい何

for (Document document : List<Document> documents) { 
    if (!fileIsPresent(document)) { 
     doSomethingWithThisResult("File is not present"); 
     continue; 
    } 
    if (!isSomethingInTheDocumentPresent(document)) { 
     doSomethingWithThisResult("Something is not in the document"); 
     continue; 
    } 
    doSomethingWithTheSucces(); 
} 

それとも

for (Document document : List<Document> documents) { 
    try { 
     fileIsPresent(document); 
     isSomethingInTheDocumentPresent(document); 
     doSomethingWithTheSucces(); 
    } catch (ProcessingException e) { 
     doSomethingWithTheExceptionalCase(e.getMessage()); 
    } 
} 

public boolean fileIsPresent(Document document) throws ProcessingException { 
    ... throw new ProcessingException("File is not present"); 
}  

public boolean isSomethingInTheDocumentPresent(Document document) throws ProcessingException { 
    ... throw new ProcessingException("Something is not in the document"); 
} 

。何が最高ですか?これをやるより良いアプローチがありますか(多分、ある種のデザインパターンを使用して)?

限り可読性が...現在、私の好みを行く例外変異体であるとして

あなたは何ですか?

4

私はあなたの小切手をリファクタリングする方が読みやすくなると思います。

for (Document document : List<Document> documents) { 
    if(checkDocument(document)) { 
     doSomethingWithTheSucces(); 
    } else { 
     doSomethingWithTheError(); 
    } 
} 

// Later: 
public boolean checkDocument(Document doc) { ... } 

あなたはそれがあなたのcheckDocument(そして、失敗した理由を知っておく必要がない場合は)ちょうどブール値を返すと、おそらく問題が何であるかをログに記録することができます。あなたのコードは、問題が何であるかを知っている必要がある場合には、このような何か:

for (Document document : List<Document> documents) { 
    try { 
     checkDocument(document); 
     doSomethingWithTheSucces(); 
    } catch(CheckDocumentException ex) { 
     doSomethingWithTheError(ex); 
    } 
} 

// Later: 
public void checkDocument(Document doc) throws CheckDocumentException { ... } 

はまたcheckDocumentは()の代わりに例外のリターン・コードのいくつかの種類を返すことができたが、私は例外が処理のために優れていると思います複雑な誤差データ。

これらのオプションを使用すると、continueブロックまたは大きなtry {}ブロックが不要になり、一般的にコードが読みやすくなります。また、後で別の場所で行う必要がある場合は、ドキュメントをチェックするロジックを再利用することもできます。

  0

場合によっては(document.isValid())...ニース!これについての考え方のねじれに感謝します... 23 9月. 082008-09-23 20:56:59

  0

ドキュメントは有効ですもっと見るoop。おそらく、すべてのコードをDocumentクラスの中に入れることができます。 24 9月. 082008-09-24 03:40:27

  0

私は(おそらく間違って)Documentクラスが密封されていると仮定していました。またはカスタムクラスではなく組み込みクラスでした。また、DocumentにisValid()メソッドを書くことは、Documentが何が有効で何ができないのかを知っている場合にのみ機能します。検証の内容によっては、伝える情報が不足している可能性があります。 24 9月. 082008-09-24 13:02:11


0

これらの2つの条件は、処理しているワークフローやコンテキストにとってどれほど重要かによって異なります。

ファイルが存在し、各ドキュメントにコンテンツがあると想定される場合、これは標準外のもので特別なケースで処理する必要があるため、例外をスローしたいと考えます。

"期待される環境"は、ファイルが出たり来たりするものであり、あるものは内容を持っているものもあればそうでないものもありますが、重要なのは、渡されたファイルのリストを取得してから、潜在的に不良データのロギングまたはアラートが望ましい場合があります。


0

私の好みは、状況が本当に例外的な場合にのみ例外を使用することです。

たとえば、私たちにとってコーダーは実際に処理するファイルがあると想定するのは当然です。ファイルが存在しない場合は、例外的な、そしておそらく回復不能な状況があります。

ただし、ファイルに何か不足がある場合は、それほど重大ではないか、より一般的な可能性があります。たとえば、初期パラメータのリストを設定していて、ユーザが期待するパラメータの1つを指定できなかった場合、デフォルト設定に戻すことができます。この種の動作は、我々のエンドユーザにいくつかの設定スクリプトとプロパティファイルを公開しているので、私たちのシステムの機能と考えられます。

例外がスローされた場合は、処理ループから抜け出すと元に戻れません。しかし、ループ内で例外がスローされただけで、「デフォルトを使用して仕様が不足しています」と表示された場合、その努力をする価値はないと思います。

要するに、私はそれが依存していると思います。上記の特定の例では、私は両方のスタイルの組み合わせを使用して終了すると思います。


1

continueは、特にループ内で使用してください。ほとんどの例外は、タイトなループで大きなパフォーマンスヒットになるスタックトレースを作成します。ヒットを避けるためには、fillInStackTraceをオーバーライドする必要があります。

しかし、一般的なルールでは、例外的な状況では例外をスローする必要があります。文書が存在し、特定のデータがあるかどうかを調べる場合は、すべてのデータがそのデータを持つことを非常に期待しない限り、続行する必要があります。しかし、存在しないか、フォーマットにマッチしないファイルが予期せぬ事象である場合は、例外を使用しないでください。


1

それは読みやすさに関するものではなく、安全なプログラミングに関するものです。エラーを検出した場合は、クライアントコードが明示的に決定しない限り(例えば再試行の場合)、クライアントコードが無視できないようにする必要があります。

また、 'if'ステートメントは、手動リファクタリングのためにロジックが誤って破損した場合に脆弱です。

独自の例からわかるように、例外によるエラーレポートは、わかりやすいものです。

P.S.個人的には、未チェックの例外を使用することをお勧めします。しかし、コードの種類によって異なります。 Mineは例外が発生しても続行する必要はないので、私はそれを報告している先頭の開始コードまで昇格させるだけです。チェックされていない例外は、その場合の作業が少なくなります。