В нашей системе у нас есть сущность Product
, которая может иметь различные пользовательские свойства.Набор свойств может отличаться от продукта к продукту и хранится в поле типа List<Property>
.Свойства имеют разные типы (строки, целые, двойные) и могут иметь некоторые специальные характеристики, например, они могут быть многозначными, могут быть значением определенного диапазона, значением из данного списка и т. Д. Значение свойства всегда содержится встроковое поле Value
.
Теперь моя текущая проблема состоит в том, чтобы реализовать проверку этих свойств, и я застрял на том, какой подход использовать в части представления результатов проверки.Требования, которые я должен выполнить: - Результаты проверки будут использоваться другими прикладными уровнями, поэтому результирующий API должен быть понятным и простым в использовании - Каждая ошибка должна иметь четкое представление - Пользователи API должны иметь достаточно информации для пониманияособенности ошибок (например, для ошибок диапазона они должны быть представлены с минимально возможным значением, максимально возможным значением и фактическим значением)
Вот подходы, которые я рассмотрел до сих пор:
Иерархия классов. Существует один базовый абстрактный класс 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))
- чепуха!).Однако это первое, что пришло мне в голову.
Перечисление ошибок и, при необходимости, иерархия классов. Все ошибки представлены с перечислением.Существует один класс 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.Еще одна проблема, связанная с этим подходом, заключается в том, что если большинству ошибок в конечном итоге потребуется дополнительная информация, мы в конечном итоге получим тот же самый номер ошибки 1.
У кого-либо есть какие-либо мысли, которыми можно поделитьсяна этих двух подходах или предложить лучший?Я буду очень признателен за любой ответ.Заранее спасибо.