3

例外を処理するのに最適な場所はどれですか? BLL、DAL、または PL ?

DAL と BLL のメソッドが例外をチェーンにスローし、PL がそれらを処理できるようにする必要がありますか? または、BLL で処理する必要がありますか?

例えば

「ExecuteNonQuery」を発行していくつかのレコードを更新するメソッドが DAL にある場合、1 つ以上の理由により、0 行が影響を受けます。さて、例外が発生したのか、それとも条件に一致する行が本当になかったのかを PL に知らせるにはどうすればよいでしょうか。PLコードで「try catch」を使用して例外を通知する必要がありますか、またはDALで例外を処理し、(-1)のような特別なコードを返して、PLが(例外)と(いいえ)を区別できるようにする必要があります行は条件に一致しました。つまり、影響を受ける行はありません)?

4

7 に答える 7

5

DAL バブルでスローされた例外を PL に渡すのは意味がありません。データベース接続を確立できなかった場合、ユーザーはどのように反応すればよいのでしょうか?

例外を処理できる場合は、例外を早期にキャッチして処理します。ヒントやログ メッセージを出力せずに飲み込んではいけません。追跡が困難な深刻な問題やバグにつながる可能性があります。

于 2010-06-14T18:47:28.317 に答える
3

これは多くの不必要な論争を伴う巨大なトピックです(大きな声で悪い情報を与える人々!)あなたがそれに対処する気があるなら、s1mm0tのアドバイスに従ってください、それはほとんど賛成です。

ただし、一言で答えたい場合は、PLに入れてください。深刻。それを回避できる場合は、エラー処理をグローバル例外ハンドラーに入れます(すべてのエラーはログに記録され、セキュリティ上の理由(特にWebの場合)で本番環境でログを検索するコードを提供する必要がありますが、開発中に完全な詳細を返します。速度の理由)。

編集:(明確化) どこでもいくつかのエラーに対処する必要があります-しかし、これは「すべての関数」の規範ではありません。ほとんどの場合、PLにバブルアップし、独自のコードで.NETのグローバルエラーを処理します。イベントハンドラーを介して3つのレイヤーすべてからアクセスできる共通ルーチンを介してそこから完全な呼び出しスタックをログに記録します(メッセージの下部にある編集を参照) )。これは、すべてのコードにtry/catchを振りかける必要がないことを意味します。予期してエラーが発生し、そこですぐに処理できるセクション、またはエラーをログに記録してユーザーに使用できない機能を通知する非クリティカルセクション(これはさらにまれで、非常に信頼性の高い/クリティカルプログラムの場合)

それとは別に、限られたリソースのアイテムを扱うときは、「using」キーワードを使用するか、キャッチなしでtry / final /endtryを使用することがよくあります。マルチスレッドロック/ミューテックス/再突入防止フラグなど。また、プログラムが引き続き機能するように、すべての場合にtry / finalを実行する必要があります(特にステートフルアプリ)。

例外を不適切に使用している場合(たとえば、IFステートメントを使用する必要があるときにバグ以外の処理を行う場合や、試してみる前にiffy操作が機能することを確認する場合)、この哲学はさらに崩壊します。

ちなみに、シッククライアントアプリでは、特に大量のデータやユーザーの入力が失われる可能性がある場合は、データを保存しようとする試行/キャッチを増やす方がよい場合があります(もちろんまだ有効ではないとマークされています)。 )。

編集:少なくともPLにロギングルーチンを持たせるためのもう1つの必要性-これは、プラットフォームによって動作が異なります。私たちが取り組んでいるアプリは、BLL / DALを3つのPLバージョン(ASP.Netバージョン、winformsバージョン、およびコンソールアプリバッチモード回帰テストバージョン)と共有しています。呼び出されるロギングルーチンは、実際にはBLLにあります(DALはエラーをスローするか、エラーを取得または再スローするものを完全に処理します)。ただし、これにより、PLによって処理されるイベントが発生します。Web上では、サーバーのログに記録され、Webスタイルのエラーメッセージ表示(本番環境に適したメッセージ)を実行します。WinFormsでは、テクニカルサポート情報などを含む特別なメッセージウィンドウが表示され、バックグラウンドでエラーがログに記録されます(開発者は完全な情報を表示するために「秘密」の何かを行うことができます)。そしてもちろん、テストバージョンでは、それははるかに単純なプロセスですが、同様に異なります。
パラメータ「whatplatform」を渡すことを除いて、BLLでそれをどのように行ったかはわかりませんが、ロギングが依存するwinformsまたはaspライブラリが含まれていないため、それでもトリックになります。

于 2010-06-14T18:13:58.667 に答える
3

簡単な答えは、場合によるということです。

何か役に立つことができる場合にのみ、例外を処理する必要があります。「役に立つもの」は、あなたが何をしているかによって異なります。例外の詳細をログに記録したい場合がありますが、これは実際には例外を処理していないため、ほとんどの状況でログを記録した後に例外を再スローする必要があります。例外にさらに情報を追加するために、例外を他の (場合によってはカスタム) 例外でラップすることができます。@mbeckish が触れているように、たとえば操作を再試行して例外から回復しようとする場合があります。ただし、永久に再試行しないように注意する必要があります。最後に (しゃれを許してください)、finally ブロックを使用して、開いている DB 接続などのリソースをクリーンアップすることができます。例外に対して何を選択するかは、それを処理する場所に影響します。ない可能性が高い」

自分で例外をスローする場合、例外のスローには大きなオーバーヘッドがあるため、「例外的な」状況でのみ例外をスローする必要があります。あなたの例では、操作によってレコードが更新されない場合に例外をスローすることを考えている可能性があることを示唆しています。これは本当に例外的なことですか?この状況で行うより良い方法は、更新されたレコードの数を返すことです。これは、ユーザーに報告する必要があるエラー状態である可能性がありますが、DB への接続が失敗したためにコマンドが失敗するなどの例外ではありません。下がった。

これは、例外処理のベスト プラクティスに関する適切な記事です。

于 2010-06-14T17:43:06.090 に答える
1

物事を正しく設定するために何をすべきかを知っている層は、例外を処理する層でなければなりません。たとえば、クエリを特定の回数再試行してデッドロックエラーを処理することにした場合は、それをDALに組み込むことができます。それでも失敗する場合は、例外を次のレイヤーにバブルさせて、この例外を適切に処理する方法を知っているかどうかを判断できます。

于 2010-06-14T17:27:25.643 に答える
0

アプリケーションのすべてのレイヤーは、例外を適切に管理する必要があります。これは、すべてのレイヤーに表示されるため、クロス カッティング コーンサーンとして知られています。統一された Enterprise Exception Block のようなフレームワークを使用すると、全体的により良いコードになると思います。この投稿を見てください

http://msdn.microsoft.com/en-us/library/ff664698(v=PandP.50).aspx

使いこなすには時間がかかりますが、そこにはたくさんの例とスクリーンキャストがあります。

于 2010-06-14T18:42:20.193 に答える
0

例外の処理方法は、技術的およびビジネス上のニーズによって異なります。複雑な、または非常に重要なデータベース更新の場合、既知のエラー バックアップの小さなリストを DL に渡す out パラメータを含めます。このようにして、既知のエラー シナリオをプログラムで解決できる場合があります。それ以外の場合は、エラーをログに記録し、ユーザーにエラーを通知する必要があります。

私は人間にエラーを通知する習慣をつけています。確かに、ログは詳細な情報を提供してくれますが、人間の応答時間に取って代わるものではありません。それだけでなく、開発者にシステム ログの監視を強制して、状況が悪化しているかどうかを確認する必要があるのはなぜでしょうか。不要なコストについて話します。

潜在的なエラー/例外を定義し、プログラムで解決する時間があれば、必ず実行してください。多くの場合、予期しないエラー/例外が発生します。だからこそ、その予期せぬ事態に備えることが重要であり、それを行うには人間を巻き込むよりも良い方法はありません.

全体として、例外処理を計画するときは守勢に立つ必要があります。プログラムは成長するか死ぬかです。成長の一部はバグの導入です。だから、それらすべてを殺そうとして車輪を回転させないでください.

于 2010-06-15T16:34:33.040 に答える
-2

あなたへの質問は、例外がどこに関連するかです。データ アクセス例外の場合は、DAL でキャッチする必要があります。論理例外の場合は、BLL でキャッチする必要があります。プレゼンテーションの例外である場合は、PL.

たとえば、DAL が例外をスローした場合、それは null または false を返す必要があります。BLL は、DAL が null を返した場合の対処方法を知っている必要があります。おそらく、それをそのまま渡したり、別の関数を呼び出そうとしたりする可能性があります。BLL が DAL から null を渡したり、特定の何かを返したりする場合、PL にも同じことが言えます。プレゼンテーション層は、問題があったことをエンド ユーザーに通知できるはずです。

もちろん、詳細な例外メッセージは表示されませんが、ユーザーに関する限り、これは良いことです。これらの例外をキャッチし、データベースや ip:port など、あなたが決定したものに報告するための柔軟なログ システムが必要です。

基本的に、懸念がデータの問題であるか論理の問題であるかに応じて処理する必要がある場合、懸念の分離の観点から考える必要があります。

于 2010-06-14T17:42:09.227 に答える