web-dev-qa-db-ja.com

例外の細分性

私は数人の友人と私との間で議論に遭遇しました。彼らはClientErrorExceptionServerErrorExceptionなどの一般的な例外を例外のフィールドとして詳細を使用することを好みますが、私は物事をより具体的にすることを好みます。たとえば、次のような例外がいくつかある場合があります。

  • BadRequestException
  • AuthenticationFailureException
  • ProductNotFoundException

これらはそれぞれ、APIから返されたエラーコードに基づいて構築されています。

以下 例外の利点 これはJavaにとって慣用的なようです。しかし、私の友人の意見は全く珍しいことではありません。

コードの読みやすさとAPIの使いやすさの点で好ましい方法はありますか、それとも本当に好みに帰着するのですか?

9
user304989

多くの異なる例外クラスがあることと、エラーテキストに詳細情報が含まれている少数の例外クラスがあることの主な違いは(たとえば)、多くの異なる例外クラスにより、呼び出しコードがさまざまな種類のエラーに異なる反応をすることができる一方で、少数のクラスのみで、あらゆる種類の例外を統一された方法で処理することが容易になります。

これは通常、トレードオフです。継承を使用することである程度軽減できます(一般的にすべてをキャッチしてログに記録したい呼び出し元の一般的な基本例外クラス、および異なる反応が必要な呼び出し元のこれらの基本クラスから派生した例外)。注意せずにYAGNIの原則に固執しないと、多くの不必要な複雑さが生じます。したがって、ガイドとなる質問は次のとおりです。

  • コードの呼び出し元が、さまざまな種類のエラーに対して、さまざまな制御フローでさまざまに反応することを本当に期待していますか?

これには万能のソリューションはなく、どこにでも適用できる頭の痛い「ベストプラクティス」はありません。この質問に対する答えは、設計しているソフトウェアまたはコンポーネントの種類に大きく依存します。

  • あなたやチームがコードベース全体を管理しているアプリケーション

  • または潜在的なすべての発信者を知らないサードパーティ向けの再利用可能なコンポーネントですか?

  • 実行時間の長いサーバーアプリケーション。さまざまな種類のエラーによってシステム全体がすぐに中断されるべきではなく、さまざまな種類のエラーの軽減が必要になる場合があります。

  • エラーが発生した場合にユーザーにエラーメッセージを表示し、プロセスを再起動するだけで十分な、短命のアプリケーションプロセス?

したがって、コンポーネントの潜在的な呼び出し元について知っているほど、例外の正確な詳細レベルを決定できます。

15
Doc Brown

答えは、私たちが話しているエラー報告のレベルによって異なります。

一般的に私はあなたの友人に同意します、あなたは彼らに問題の原因を伝えるために必要以上にきめ細かくすべきではありません。

Nullを参照する一般的なよく知られた例外(NullReferenceException)がある場合は、独自のMyObjectIsNullExceptionを作成しないでください。それは単に人間の通訳者に混乱の層を追加するだけで、何も明確化しないことを学ぶための追加の事柄です。

例外が特別で、根本的な原因をカバーする事前定義の例外がない場合にのみ、独自の例外を作成する必要があります。

ただし、そこで停止する必要はありません。一般的なエラーは、コンポーネントの1つで発生する可能性があり、問題があることを伝えたい場合がありますコンポーネント内。何が問題だったのかだけでなく、どこで問題が発生したのか。次に、最初の例外をMyComponentExceptionでラップするのが適切です。それはあなたに両方の世界のベストを与えるでしょう。

まず、コンポーネントに問題が発生したことが明らかになります。より低いレバーでは、特定の原因は内部の例外になります。

1
Martin Maat