システムエラー、例外処理(Java、C ++、Perl、PHPなど)を公開/許容/回復するための設計パターン/アプローチを推奨する


13

システムエラー、例外処理(Java、C ++、Perl、PHP)を公開/許容/回復するための設計パターン/アプローチを推奨できますか?

いくつかのエラーを報告する必要があります。

一部のエラーは、内部的に処理することができます(再試行によるか、重要ではありません(無視できます)。

それらをキャッチするコードをどのように構成しますか?

ただし、すべてのエラーを記録する必要があります。

どんなベストプラクティスがありますか?

そして、それらの影響を受けるコンポーネントを完全にテストできるようにそれらをシミュレートするには?

いくつかの現代のプログラミング言語に適用可能な一般的な非プログラミング言語固有の質問ですが、Java、C ++、PHP、およびPerlのパターン、アプローチ、哲学の例図を歓迎します。

(stackoverflowでも尋ねました:https ://stackoverflow.com/questions/7432596/recommend-a-design-pattern-approach-to-exposing-tolerating-recovering-from-systemです が、プログラマーにも尋ねるべきだと思いましたプログラマーのQ&Aは、より広範なソフトウェア/プログラミングの問題をカバーしているのに対し、stackoverflowは技術的な実装に関するものです(IMHO)。


2
私にとって、あなたの質問はあまりにも一般的すぎて、効果的に答えられるには無制限のようです。いくつかのより具体的なケースと特定のアプリケーションタイプ/環境(たとえば、GUIアプリ/サーバー/ ...)に制限するようにしてください。
ペテルトレック


@PéterTörök、mikeraは良い答えを提供します。
therobyouknow

回答:


16

フェイルファーストは優れた設計アプローチであり、おそらくパターンとしてカウントすることができます:http : //en.wikipedia.org/wiki/Fail-fast

また、いくつかの原則が役立つこともわかっています。

  • 各関数/モジュールへのインターフェースの一部として例外を考慮してください -すなわち、それらを文書化し、必要に応じて/あなたの言語がそれをサポートしている場合、チェック例外を使用してください。
  • 失敗を決してごまかさない -失敗した場合は、続行方法を「想定」する試みを続けようとしないでください。たとえば、nullケースの特別な処理は私にとってコード臭いです:メソッドがnull以外の値を必要とする場合、null(NullPointerExceptionまたは理想的にはより記述的なIllegalArgumentExceptionのいずれか)に遭遇するとすぐに例外をスローする必要があります。
  • 例外的なケースと通常のケースの単体テストを作成します -そのようなテストはセットアップが難しい場合がありますが、システムが障害に対して堅牢であることを確認したい場合は価値があります
  • エラーがキャッチされ処理された時点でログに記録します(エラーがログに記録されるのに十分な重大度であると想定)。これは、原因を理解し、エラーを処理するアプローチがあったことを意味するため、ログメッセージを意味のあるものにできるからです。
  • 例外は、本当に予期しない状態/障害に対してのみ使用してください。関数が実際に予期される方法で「失敗」した場合(たとえば、ポーリングで利用可能な入力があるかどうかを確認し、何も見つからない場合)、例外をスローせずに通常の応答(利用可能な入力なし)を返す必要があります
  • 優雅に失敗します(Steven Loweの功績です!) -可能な限り終了する前にクリーンアップします。通常、変更を巻き戻したり、トランザクションをロールバックしたり、「最終」ステートメントまたは同等のリソースを解放します。クリーンアップは、明確さと論理的な一貫性のために、リソースがコミットされたレベルと同じレベルで行うことが理想的です。
  • あなたが失敗しなければならない場合、大声で失敗します -あなたのコードのどの部分も処理することができなかった(つまり、捕まえられず、処理されずにトップレベルに浸透した)例外は、あなたに注意を向ける即時の大声で目に見える失敗を引き起こすはずです。通常、プログラムまたはタスクを停止し、完全な例外レポートをSystem.outに書き込みます。

1
また、正常に失敗-可能な限り終了する前にクリーンアップ
スティーブンA.ロウ

考慮すべき事項について明確なポイントを得るために、@ mikeraを+1してください。おそらく受け入れられる答えで、私は他の人が貢献するためにもう少し長く開いたままにします。
-therobyouknow

+1 @Steve A. Lowe-ユーザー中心の設計用。たとえば、一時ファイルを残さないでファイルを保存するようなものです。質問リストの関連トピックとして、「データの衛生」に関する質問を参照してください。
-therobyouknow

5

Javaと.NETで例外を処理し、例外をどのように/いつ/なぜキャッチするかについて多くの記事を読んだ後、潜在的な例外が発生するたびに頭の中で進む次のステップを思いつきました。例外(Java)をキャッチする必要があります...たとえ発生しない場合でも(ため息...)。そして、少なくとも私にとっては、うまくいっているようです:

  1. その例外でできることは何かありますか(ロギングを除く)?答えが「はい」の場合、回避策コードを記述し、回避策が例外をスローする可能性がある場合は、2に進みます。
  2. 例外をランタイム例外にラップし、スローして、3に進みます。
  3. 可能なデータベース/プロセストランザクションが開始された上位レベルのクラスで、例外をキャッチし、トランザクションをロールバックし、例外を再スローします。
  4. 最上位クラス(トランザクションが開始されたクラスの場合もあります)で、slf4j(たとえばlog4jと結合)やlog4netなどのロギングフレームワークを使用して例外をログに記録します。可能であれば、アプリケーションの開発者で構成される配布リストに例外を直接電子メールで送信します。
  5. GUIがある場合、問題の原因を最もわかりやすい方法で示すエラーメッセージを表示します。例外/スタックトレースを表示しないでください。ユーザーは気にせず、それがNullPointerExceptionであることを知る必要はありません。

また、ステップ0を追加する必要があります。ここでは、データエラーのために複雑な処理を実行できない場合に、意図的に「ビジネス」例外(「例外」クラスを拡張することで作成する新しい例外)と呼ばれるものをスローしていますが、分析中に例外ケースとして識別されたために発生することがわかっています。

ロギングの部分を除き、「mikera」によって書かれたポイントに完全に同意します。例外を1回だけ記録する必要があることを追加します

また、作成しているのがAPI / Frameworkである場合、リストしたステップは異なる場合があります。そこで、開発者が自分の過ちを理解するのを助けるために、うまく設計された例外を投げることは必須です。

例外のテストに関しては、モックオブジェクトを使用して、クラスが「1つのことを行う1つのクラス」のベストプラクティスを順守していれば、例外的であろうとなかろうと、ほぼすべてをテストできるはずです。また、個人的には、最も重要ではあるが隠されたメソッドを「プライベート」ではなく「保護」としてマークし、あまり手間をかけずにテストできるようにします。それとは別に、例外のテストは簡単で、例外を引き起こし、それをキャッチすることで発生する例外を「期待」するだけです。例外が発生しない場合は、ユニットテストケースエラーがあります。


アプローチとしてlog4jに@Jalaynを1つ追加します。これは私が使用しているものなので、他の人も同様に知っているようになります。
-therobyouknow

0

オブジェクトを正しい方法で構築します。外部要因を心配する必要はありません。例外を利用することを選択した場合、オブジェクトが何かで失敗した場合、オブジェクトに例外をスローさせます。

すべてのオブジェクトが正常に機能するようになれば、設計でエラー処理の責任の階層を明確にするのはかなり簡単になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.