web-dev-qa-db-ja.com

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

システムエラー、例外処理(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)。

13
therobyouknow

Fail fastは優れた設計アプローチであり、おそらくパターンとして数えることができます: http://en.wikipedia.org/ wiki/Fail-fast

また、いくつかの原則が役立つことがわかりました。

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

Javaと.NETで例外を処理した後、例外をキャッチする方法/時期/理由についての記事たくさんを読んだ後、ようやく次の手順を思いつきました。例外が発生する可能性がある場合、またはキャッチしなければならない例外(Java)が発生した場合でも、頭の中を通り抜けます(Javaの場合)。

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

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

伐採部分を除いて、私は「ミケラ」が書いた点に完全に同意します。例外は一度だけ記録のみであることを追加します。

また、-記述している手順がAPI /フレームワークの場合、ここに記載されている手順は異なる場合があります。そこでは、うまく設計された例外を投げることは、開発者が間違いを理解するのを助けるために必須です。

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

5
Jalayn

オブジェクトを正しい方法で構築し、外部要因について心配しないでください。例外を利用することを選択した場合は、オブジェクトがfailで例外をスローするようにします。

すべてのオブジェクトが正しく機能するようになれば、デザイン内でエラー処理の責任階層を明確にすることはかなり簡単になります。

0
Yam Marcovic