19

マイクロソフトがアプリケーションブロックを導入して以来、私は例外処理アプリケーションブロックを使用する人々にぶつかっています。私は最近自分自身を詳しく調べて、基本的な機能を次のように要約します(それが何をするかをすでに知っている場合は、次のブロックをスキップしてください):

例外処理アプリケーションブロックは、次の主要な例外処理タスクを一元化し、構成ファイルで完全に構成可能にすることを目的としています。

  • 例外のログ記録
  • 例外の置き換え
  • 例外のラッピング
  • 例外の伝播

ライブラリは、trycatchブロックを次のように変更することでこれを行います。

try
{
  // Run code.
}
catch(DataAccessException ex)
{
    bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Policy");
    if (rethrow)
    {
        throw;
    }
}

ポリシー名のapp.configで指定されている内容(ドキュメントについてはこちらを参照)に基づいて、HandleExceptionは...

  • 完全に新しい例外をスローします(元の例外を置き換えます)
  • 元の例外を新しい例外でラップし、それをスローします
  • 例外を飲み込む(つまり何もしない)
  • 元の例外を再スローしますか

さらに、事前にさらに多くのことを実行するように構成することもできます(たとえば、例外をログに記録します)。

ここに私の問題があります。例外が置き換えられるか、ラップされるか、飲み込まれるか、または再スローされるかにかかわらず、構成可能にすることがどのように有益であるかを完全に理解できません。私の経験では、例外処理の動作を変更するときに周囲のコードまたは呼び出し元のコードを変更する必要があるため、この決定はコードを作成するときに行う必要があります。

たとえば、特定のポイントでスローされた特定の例外が再スローされるのではなく飲み込まれるように再構成すると、コードが正しく動作しなくなる可能性があります(catchブロックの後に、例外が発生したときに実行してはならないコードがある場合があります)。例外処理で考えられる他のすべての変更についても同じことが言えます(たとえば、replace-> rethrow、swallow-> wrap)。

したがって、私にとって重要なのは、例外処理ブロックが実際には存在しない問題を解決するということです。例外のロギングと通知ビットは問題ありませんが、他のすべてのものはオーバーエンジニアリングの完璧な例ではありませんか?

4

6 に答える 6

13

制御フローに例外を使用する場合は、ポリシーベースの例外処理を避けたいと思うでしょう。

ただし、回復不能として扱いたい例外(バックグラウンドタスクが失敗した、ソケットが切断された、ファイルが削除されたなど)の場合は、構成可能なポリシーベースの例外処理が必要になる場合があります。

たとえば、APIを開発している場合、API内のすべての関数に、標準の例外(ArgumentExceptionなど)のみをスローさせ、内部の非標準の例外の場合は独自のライブラリ固有の例外をスローさせたい場合があります。 (例:)MyLibraryException。このタイプの場合、重要なのは何かが正しく機能しなかったことです。あなたは例外を選び出し、何が悪かったのかを理解しているのではありません。あなたは単に何かがうまくいかなかったという事実を認めているだけであり、あなたは今何かをすることになっているということです。

それはあなたが何をするかは実際には重要ではないので、そのいくつかは設定可能でなければなりません。ユーザーにメッセージボックスを表示しますか?モーダルまたは非モーダル?例外をログに記録しますか?例外をどのようにログに記録しますか?ロギングWebサービスを呼び出しますか?ログファイルに追加しますか?Windowsイベントログに書き込みますか?データベースにエントリを挿入しますか?2つのデータベースにエントリを挿入しますか?それはあなたのアプリケーションの残りの部分には本当に重要ではありません。例外の処理方法の選択は、アプリケーションの他の部分と完全に直交しています。

(余談ですが、これは、構成可能なポリシーベースの例外処理にアプローチする方法ではありません。コンテナーに例外ロガーインターセプターを登録するなど、AOPスタイルを好む傾向があります。)

于 2009-01-03T02:32:25.377 に答える
5

回復可能な状態を持たない関数を開発しているときに、この問題に遭遇します。このポリシー主導の例外処理は実際に有用であり、このプロジェクトの一部である他のすべての開発者が回復不可能な例外の標準に実際に準拠していることを保証すると思います。

上記のポスターに同意します。制御フローに使用している場合は、ポリシー ベースの例外に近づかないことをお勧めします。

于 2009-01-03T03:24:18.097 に答える
4

「例外処理ブロックは、実際には存在しない問題を解決する」という声明に同意する必要があります。私はそのブロックをリリース以来使用してきましたが、それを使用して実際に多くのことを得ているとはほとんど感じません. うーん、ちょっと頭が痛いかも。:)

開始する前に、WCF サービス境界機能での例外シールドが気に入っていることを認めます。ただし、これはかなり最近追加されたもので、コーディングは含まれず、属性と構成のみであり、ブロックの通常の販売方法ではありません。これは、マイクロソフトがhttp://msdn.microsoft.com/en-us/library/cc309250.aspxで示している方法です。

代替テキスト

私の目には、上記はフロー制御です。

try
{
  // Run code.
}
catch(DataAccessException ex)
{
    bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Policy");
    if (rethrow)
    {
        throw;
    }
}

フロー制御の側面を上記のコードと組み合わせると、間違いなく間違ったコードを間違ったように見せることはありません。(if (rethrow) コンストラクトはあまり抽象化を提供しないことに注意してください。) これにより、ポリシー定義に慣れていない開発者にとって保守がより困難になる可能性があります。構成ファイルの が変更された場合postHandlingAction(ある時点で変更される可能性があります)、アプリケーションがテストされたことのない予期しない方法で動作していることに気付くでしょう。

ブロックがフロー制御を処理せず、単にハンドラーをチェーンすることを許可した場合、おそらく私はそれを好ましくないとは思わないでしょう。

しかし、おそらくそうではありません。私は実際に次のように求められたことを覚えていません。

  • 例外を処理するときに新しい機能を追加します (たとえば、イベント ログへのログ記録に加えて、電子メールの送信も行います。実際、既に例外を自分でログに記録している場合は、ログ ブロックが独自にそれを行うことができます。:))
  • 「ポリシー」全体で例外処理動作 (スワロー、再スロー、または新規スロー) を変更します。

私はそれが起こらないと言っているわけではありません (誰かが話を持っていると確信しています!); 私は、例外処理アプリケーション ブロックがプログラムの理解と保守を難しくしていると感じています。これは通常、ブロックによって提供される機能を上回っています。

于 2010-01-21T08:36:02.650 に答える
2

これはエンジニアリングを超えているとはまったく思いません。実際には。例外が中央のハンドラーを通過できるという事実は、私の仕事では良いことでした。私はすべての例外を食べる開発者を持っていました-処理されているかどうかにかかわらず、それがトップにバブルしてエンドユーザーの前に何か警告を発したり、キャッチされなかったときにサービス/デーモンをひどく台無しにしたりしないようにします.

このポリシーを使用すると、再起動したり、アプリ全体に不必要にログ ロジックを散らしたりすることなく、いつでもログを開始できます。アプリをオフラインにすることなく、例外などをすべて監視できるようになりました。

あなたが私に尋ねるなら、スマートプログラミング...

于 2009-01-03T03:38:07.273 に答える
1

簡単に言うと、リリースコードとデバッグコードで異なる例外処理が必要な場合は、それが役立ちます。

于 2009-01-03T02:16:42.537 に答える
0

私の意見では、例外処理ブロックを使用することの1つの実際の価値は、catchブロックの1行のコードから始まります。

bool rethrow = ExceptionPolicy.HandleException(ex、 "データアクセスポリシー");

1行のコード-どれだけ簡単にできますか?1行のコードの背後にあるポリシーは、構成されているため、ソースコードを再コンパイルすることなく、ポリシーへの割り当て/更新を簡単に実行できます。

前述のように、例外ポリシーは実際には多くのアクションを実行できます-ポリシーで定義されているものは何でも。catchブロック内に示されているように、1行のコードの背後に複雑さを隠すことは、私が本当の価値を見るところです。

私は複雑だと思いますが、過剰に設計されていません。したがって、構成を簡単に変更できる柔軟性を備え、同じ1行のソースコードを使用して例外の処理/ロギングの方法を変更する必要がある場合、メンテナンス中に大きな利益が見られると思います。

于 2009-01-03T03:04:33.643 に答える