2011-01-04 8 views
1

3層のアプリフロントエンドドメインとデータアクセスがあります。私はコールスタック内の高い例外をキャッチするのは良い考えであることを読んだことがある...ので、私は、データ・アクセス例外を取得する場合、ドメイン層は、単に最終的には、そうn段を扱う場合、呼び出しスタックの例外が高いキャッチ?

ような試み{

を行います} finally { //クリーンアップ }

となり、データアクセス例外がフロントエンドレイヤに浸透します。これは、フロントエンドのレイヤーを内面とすることでレイヤーを破ることはありませんか?私は、各レイヤーがハンドラまたはラップして、その呼び出しレイヤーに処理できない例外をスローする必要があると思います... 任意の考えですか?

答えて

1

これまでのフィードバックがたくさんありましたが、私はあなたにそれを渡します。

ルール#1。あなたが実際に処理しようとしている例外をキャッチするだけです。ハンドルとは、クライアントの要求を継続できるように処理することです。情報をログに記録するのに十分な時間を捉えることができます(乱用しないでください。通常、スタックは十分な情報です)。あるいは、より簡単に伝播する別のエラー(ランタイムベース)に変換してください。しかし、あなたがそれを処理することができない場合は、それをキャッチする気にしないでください。それは無用で混乱する余分なコードです。あなたが記録したり変換したりしても、あなたは再暴行を終わらせます。

ほとんどの場合、例外を処理することはできません。本当に。多くはこれを把握していません。しかし、実際には、IOExceptionをディスクに読み書きすると、ゲームが終了します。その要求はユーザーに対して完了できません。あなたのネットワークが不安定で、データベースと話すことができない場合は、同じことをしてください。

ルール#2。あなたが処理することができない例外を取得する場合、あなたが行うことができる唯一のことは、それがユーザに役立つような方法で失敗しようとすることです。これは、後の分析(元のスタック/原因を含む)のためにログに記録し、できるだけ有用なものをユーザーに報告することを意味します。システムを一貫した状態に保つために、必要なものを掃除してください。

エンドユーザーとのこの通信が非常に高いレベルで行われることを考えれば、通常、そのレベルでキャッチする必要があります。たいていの場合、私は、それが開始点であることと、ユーザーに記録して報告するためにキャッチしたトップレベルとの間の例外処理にはほとんど価値がないことがわかります。私はしばしばRuntimeExceptionの形式に変換しますが、これは層を介した伝播を容易にするためだけです。

最大の最も重要なことは、通常は例外を処理できないことを認識することです。そのために作成するコードはできるだけシンプルにする必要があります。

+0

ストリームからドキュメントを逆シリアル化しようとしているときに例外が発生したとします。部分的に構築されたドキュメントを放棄し、そのファイルがロードできなかったことをユーザに通知すると、その例外を「処理しましたか」? – supercat

+0

@supercat - はい。あなたが合理的にできる限り。間違ったことのような良いエラーメッセージを提供することができます。しかし、ドキュメントが逆シリアル化に失敗した場合、さらに何をすることができますか? – rfeak

+0

破棄されたドキュメント以外の状態を破損しない例外と、破損したシステム状態を示す例外との違いを、どのように伝えるべきですか? – supercat

0

レイヤリングは、これが壊れてしまうような純粋なアイデアだとは思わない。

ラッピングと再スローイングでも大きな価値はありません。

サービスレイヤで例外を処理すると何が問題になりますか?それは防衛の最後のライン、ラインの終わりでなければなりません。この設計により、サービスは例外をログに記録することができ、ユーザーフレンドリーなメッセージをUIに表示して表示することができます。

+0

サービスレイヤと言うとき、フロントエンドレイヤーを意味すると思いますか?それは、それの下のレイヤーから情報を処理する必要のあるコードで、ラインレイヤーの上端を乱雑にしていませんか?例:何らかの理由でデータアクセス呼び出しを3回行い、それを渡したレイヤにその状態が格納されている場合、フロントエンドレイヤはどのようにアクセスしますか?それは一番上の層をかさばっていませんか?このパターンに従うサンプルコードはありますか? – treefrog

+0

いいえ、「サービス」は「フロントエンド」ではありません。定義上、それが泡立つと、下のレイヤーがそれを処理できないことを意味します。 「ハンドル」は、スタックトレースのログを意味するものではありません。まれな状況や例外的な状況について何かを行うことを意味します。どのような状態を意味しますか? SQL例外が発生した場合は、SQLエラーコード以外に何が必要ですか?必要に応じてカスタム例外に追加します。私はそれが何かを大きくするとは思わない。サンプルコードはありません。 – duffymo

+0

レイヤに混乱を与えないようにします。私は "frontend domain and db layers"と言っていて、あなたは "services"と返答しました。だから私はLayer1 - 層n(最も内側)と言うつもりです。扱いが3回再試行を意味する例で言えば、私はこれまでどこかの回数を保存する必要があります。例外が発生した場所、その上の層n-1。 (contd ... in next comment) – treefrog

0

通常は、コールスタックの上位の例外をキャッチしたいが、それは理にかなっている点までしかない。データレベルで例外を処理してログに記録し、フロントエンドにメッセージを戻すだけであれば、単純で柔軟な処理が可能です。

個人的には、試してみる必要がある場合は、最後に、発信者に渡すよりも、状況を把握してやりたいと思います。良いデザインルール(通常はKISSのような別のルール)には常に例外があることに留意してください。

0

ここには3つのインターロックの問題があります。

まず、常に例外を再ラッピングすることができますが、それはどのような価値がありますか?最初の例外の周りにもっと多くのレイヤーを作成しています。私は、例外に関する追加情報を提供できるとき、または最初の例外が別の例外を引き起こすときにのみ、例外をラップします。

第2に、例外の考え方は、関数が正常に完了できないと応答することです。あなたは、問題に対処するのが最も理にかなっている場所で例外をキャッチする必要があります。コードに「別の代替」がある場合、その時点で例外がトラップされます。それ以外の場合は、ユーザーまたは開発者が作業するためにログに記録します。

第3に、try/finallyブロック。これらは、例外によってリソースがオープン状態または割り当てられた状態でハングアップする場合に便利です。私はいつもtry/finallyを使用してオープンされたリソースを整理します(私のお気に入りはjava.sqlのStatement/ResultSetです)。実際に優れたプログラマは、メモリリークやリソースの巨大な制約を生かさずに正常に回復する方法として、コードの中にこれをたくさん持っています。

関連する問題