ようこそ。睡眠不足なプログラマのチラ裏です。

いまさら聞けない.NET テクノロジの例外管理の設計および実装のガイドライン その1

例外管理ポリシー

アプリケーションの内部で発生した例外を管理する際には、いくつか考慮すべきことがある。


まず、「発生した例外をどのタイミングで捕捉するのか」、「捕捉した例外をどのように処理するのか」、
そして、「捕捉した例外をどのように伝播させるのか」などである。
こういった例外に対するポリシーは、システムの要件や規模によって変化するのが常で、
例外管理システムを担当する設計者の思想と過去の経験などが大きく影響してくるが、
一般的にベストプラクティスとして知られる基本的なポリシーがある。
例えば、例外を捕捉するタイミングは、以下のいずれかの例外処理を行うケースが考えられる。

1.ログの記録のために情報を収集するケース
2.例外に何らかの関連情報を追加するケース
3.リソースの解放などのクリーンアップ・コードを実行するケース
4.復旧を試みるケース


逆に言えば、これらの条件に合致しないような場合は、例外を捕捉せず、
呼び出しスタックの後方にある上位レイヤに向かって素直に伝播させていくのが基本形である。
無闇にすべての例外を捕捉すると、コードの保守性を失わせることになるし、パフォーマンスの観点からも推奨されない。


例外管理と保守

保守の容易な柔軟性に優れたアプリケーションを構築するには、
アプリケーションに適した、適切な例外管理手法を採用する必要がある。
例外管理システムの設計にあたっては、一般的に以下の機能を持たせることが推奨とされる。

1.例外の検出(カスタムアプリケーション例外の検討)
2.ログの記録および通知(と記録方法の選択)
3.システム運用を支援するための、外部から監視できるイベントの生成


本格的にソフトウェア開発をはじめる前段階で、一貫性のある例外管理システムを設計することにより、
実際にシステム開発を行うときに、既存のコードベースに対して例外処理を強引に埋め込む必要がなくなる。
例外管理システムは、適切にカプセル化し、ログの記録と通知を抽象化し、
アプリケーションのビジネス ロジックから切り離さなくてはならない。
また、アプリケーションの現在のステータスに関する情報を与えるような、
オペレータによる監視が可能なメトリクスを生成できる必要がある。
これにより、発生している問題を迅速かつ正確にオペレータに通知し、
開発者とサポート部門に問題解決のための有益な情報を提供することができる。


「例外」は「エラー」であるとは限らない

.NET共通言語ランタイム(CLR)は、例外を生成するモジュールが、
例外処理を行うモジュールとは異なる言語で書かれていたとしても、
プログラムに対して例外を統一的な方法で通知できるプラットフォームを用意している。


例外とは、コード内の暗黙の仮定に対する違反を表しているものである。
例えば、コードが存在を仮定しているファイルにアクセスしようとしたが、
対象のファイルが存在しなかった場合に例外が送出される。
しかし、コードがそのファイルの存在を仮定せずに、
先に対象ファイルの存在をチェックしているようなシナリオにおいては、
例外は必ずしも生成されないと言うことができる。


例外は必ずしもエラーであるとは限らない。例外がエラーを表すかどうかは、
その例外が発生したアプリケーションの仕様によって決定される事項である。
たとえ対象のファイルが見つからなかったとしても、送出される例外が
そのアプリケーションにとってのエラーを表すかどうかは、シナリオによって左右される。


.NETの例外と例外階層

すべての例外クラスは、共通言語仕様(CLS)に準拠し、
System名前空間内のException基本クラスから派生する必要がある。
.NET Frameworkクラス ライブラリ(FCL)は、さまざまなタイプの一般的な例外を処理するために、
網羅的な例外階層を用意しているが、これらはいずれも最終的にはExceptionから派生している。
また、例外は .NET ランタイムが生成することもあり、独自の例外階層を作成して表現することも可能。


ApplicationException は、すべてのアプリケーション固有の例外クラスの基本クラスである。
これはSystem:Exceptionから派生しているが、新たな拡張機能は何も持っていない。
カスタムアプリケーション例外を作成する場合は、必ずApplicationExceptionから派生させるのが流儀。



※注意:ApplicationExceptionから派生させるのが流儀だったのは、.NET Framework1.x時代までの話で、
.NET Framework2.0以降からはすべての派生例外クラスはSystem.Exceptionから派生することが流儀となっています。
NET Framework2.0以降からは、カスタム例外はApplicationExceptionから派生しないでください。 

 http://msdn.microsoft.com/ja-jp/library/ms229007.aspx



■例外クラス階層