次のような検証メソッドから例外をスローすることをお勧めしますか?
ValidateDates();
ValidateCargoDetails();
これとは別に:よく使用される堅牢な検証デザインパターンはありますか?
ValidationFailuresを含むValidationResultオブジェクトを返すことをお勧めします。論理コーディングの一部として例外を使用しないでください。例外は例外です
私は通常、入力の検証にvisitor pattern
を使用します。すべてのエラーをリストまたはユーザーに表示するものに蓄積します。ロジックは次のようになります。検証エラーが見つかった場合はリストをチェックし、見つかった場合はユーザーに通知します。それ以外の場合は問題ありません。
IMO、検証エラーは例外的なものではないため、1つのように扱うべきではありません。
私はそれがすべてあなたが検証をしている/どのように行っているかに依存すると思います。しかし、結局のところ、開発者は返された結果を無視することをいつでも選択できます(これは彼らの問題です)。そうするための明示的なコードを書かずに例外を無視することはできません。
多くは、例外的な検証の失敗がどれほど重要であるかによって異なります。
検証の失敗がまれで、発生したときに重大または致命的である場合は、ExceptionsまたはAssertionErrorsを使用します。ほとんどのパーサーは例外を使用しており、これらは処理を続行できないことを示しています。
通常の操作と同様に検証の失敗が予想され、処理を続行できないことを示さない場合は、ビジターパターンを使用するか、問題のリスト(空の場合があります)を返すことをお勧めします。
スローする例外は、アプリケーションのフローを制御するために使用しない必要があります。名前が示すように、検証が一般的に失敗する可能性がある一方で、例外的なケースで発生します。また、高価であり、パフォーマンスに影響を与えます。
ブール値と理由の文字列を返すことにします。
無効なデータを入力するユーザーは、まさに例外の定義です。ソリューションのビジネス要件を作成するときは、常に非エラーパスをメインフローとして作成し、エラーパスを例外パスとして作成します。検証に例外を使用することは完全に許容されます。例外を使用して検証することで、処理方法の順序に優先順位を付け、アーキテクチャスタックのレベルに応じてエラーを異なる方法で処理することもできます(エラーを説明する文字列はデータアクセス層ではほとんど役に立ちません)。
私はこれを写真に取り入れたかったのですが、ブログへのRADZSERGの回答: エラーコードを返すよりも例外をスローする方が良い理由 。
つまり、戻り値の型としてブール値を使用するように制限する必要はありません...
例外を使用するかどうかを教えていません
しかし、その特定の記事に関しては、最初に悪いコードを作成してから、それを改善しようとします。最初に適切なコードを作成し、例外を使用する方が良い理由を説明します。これが私の例です
class TooManyLoginAttempts extends ValidationError{} if ($hasTooManyLoginAttempts) { return new TooManyLoginAttempts() } ... $validationResult = $this->validate(); if ($validationResult instanceof ValidationError) { $this->errorLogger->log($validationResult->getMessage()); }
また、説明されているすべての問題を解決します
–マジックナンバーなし
–アプリケーション全体でエラーコードが発生する問題を解決しています
–私のコードははるかに短く、オープンクローズの原則に従います
私はここから来ました: Validate()メソッドで例外をスローするか、bool値を返す方が良いですか? ロックされています。
正直なところ、私はこれらすべてについてかなりの危機に瀕しています。時々私はビジターパターンも構築していますが、それは私が例外を再実装しているだけだと本当に感じています。
私がビジターパターンについて絶対に気に入らないのは、6つのレベルが深く、あなたがあなたを壊す必要があることに気付いた場合haveをチェックすることです上記のすべてのレベルで結果。
これは、実際にバグを引き起こす可能性のある多くの定型コードを意味します。
例A
をチェックした場合はどうなりますか?検証されませんが、コードは、適切に初期化されたB
に実際に依存するA
をチェックし続けますか?複雑な検証ロジックでは、これは多くの異なるパスで発生する可能性があります。エラーが発生しやすいです。
一方、私は(カスタム)ValidationExceptions
を使用しましたが、重大な問題は発生していません。検証されないものにヒットすると、他のすべての検証ロジックがスキップされることが保証されます。これは、コードを単純化するための大きなメリットです。
"アプリケーションのフローを制御するために例外をスローすることはできません。"-他のケースの99%については同意しますが、検証ロジックのこれは、実用主義ではなく、教義に基づいているように私には思えます。
performaceについて:パフォーマンス上の理由は、ユーザー入力の検証ロジックでは99%の問題ではありません。これは、タイトなループではほとんど行われないためです。
要約:「例外は例外的なもののためのものです」ドグマを無視し、(カスタム!)スローする例外を作成してトップレベルでキャッチし、それがあなたのために働くかどうかを確認してください。私にとってはそうです。