私たちのシステムには、さまざまなカスタムプロパティを持つ可能性があるエンティティProduct
があります。プロパティのセットは製品ごとに異なる場合があり、タイプList<Property>
のフィールドに格納されます。プロパティは異なる型(文字列、int、double)であり、いくつかの特殊な特性を持つかもしれません。それらは多値でもよく、特定の範囲の値でもよいし、指定されたリストなどからの値でもよい。プロパティの値は常に文字列フィールドValue
に含まれる。検証エラー階層設計
現在、私の現在の問題はこれらのプロパティの検証を実装することであり、検証結果の表現の一環としてどのようなアプローチを取っているのでしょうか。私が満足しなければならない要件: - 検証の結果は他のアプリケーション層で使用されるので、結果として得られるAPIは明確で使いやすいものにしてください - それぞれのエラーには別個の表現が必要です -
クラス:エラーの詳細を理解するための情報(例えば、彼らは最小限の可能な値、最大可能値と実際の値に提供されるべき範囲エラー用)
ここでは、私がこれまで考えられてきたアプローチがあります階層。 1つの基本抽象クラス
ValidationError
があり、それぞれの特定のエラーは継承クラスに反映されます。エラーに詳細がある場合、対応するクラスにはすべての情報を格納するために必要なフィールドがあります。例:public abstract class ValidationError { // common fields and methods, if any } public class IncorrectFormatValidationError : ValidationError { // just empty class, nothing to add here } public class RangeValidationError : ValidationError { public object MinValue { get; set; } public object MaxValue { get; set; } }
このアプローチは、実際には空のクラスの多様性のために私にとっては冗長なようです。そのようなAPIの使用法は正しいとは思われません(
if (typeof(error) == typeof(RangeValidationError))
- ナンセンス!)。しかし、これは私の頭に来た最初のことです。エラー列挙型、必要な場合はクラス階層型。すべてのエラーは列挙で表されます。ほとんどの場合に使用される1つのクラス
ValidationError
があり、特定のエラーに追加情報が必要な場合は、基本的に最初の方法と同じ方法で継承者が作成されます。例:public enum ValidationErrors { IncorrectFormat, ValueNotWithinRange, ... } public class ValidationError { public ValidationErrors ErrorType { get; set; } public ValidationError(ValidationErrors type) { this.ErrorType = type; ... } // common fields and methods, if any } public class RangeValidationError : ValidationError { public object MinValue { get; set; } public object MaxValue { get; set; } public RangeValidationError(object minValue, object maxValue) : base(ValidationErrors.ValueNotWithinRange) { ... } }
このアプローチは、はるかに優れていますが、欠点もあります。最大の問題は、APIのユーザーとして、タイプが
ValueNotWithinRange
のエラーが発生した場合、タイプRangeValidationError
のクラスを扱っていることを保証できないことです。そうでない場合はどうしますか?私はAPIを開発しているonylではないので、このような状況が存在することさえ防止する設計レベルの機能を持っていたいと思います。このアプローチのもう一つの問題は、ほとんどのエラーが最後にいくつかの追加情報を必要とする場合は、我々は最終的に同じaprroach番号1
になってしまいますということです。誰でもこの2つの方法で共有するために、任意の考えを持っていますか、より良いものをお勧めしますか?私はどんな応答も高く評価します。前もって感謝します。
実際、この方法で階層の重複を避けることができますが、抽象的なValidatorの追加ダウンキャスティングも導入します。 Validatorを型パラメータに変更することを提案します。 – Basilevs
@Basilevs:階層ルートに存在しないメンバーにアクセスする必要がある場合は(たとえ 'Min'や' Max'プロパティなど)、ダウンキャストが必要になります( 'ValidationError'階層でさえ)。唯一の他の方法は、実行時に動的にプロパティ値にアクセスする機能を構築することです。リフレクションを使用することと同じ道徳的なもので、基本的な問題は同じです:型の安全性の損失です。 – Jon
@ジョン、応答のおかげで。いいえ、私は今までバリデーターを持っていません。すべての検証はいくつかのBLレベルの方法で行われます。しかし、彼らの紹介について考えてみる価値はありますか?しかし、もしそうなら、私たちはエラーと同じ問題に直面しています(質問に記載されています)、そうではありませんか? – Andrei