Где должно происходить преобразование типов для ввода формы — перед проверкой, как часть проверки или другое?

#design-patterns #validation #type-conversion

#шаблоны проектирования #проверка #преобразование типов

Вопрос:

У меня есть HTML-форма, которая собирает ряд чисел в текстовых полях.

Логически мне нужно сделать следующее, но я не могу придумать способ структурировать его так, чтобы он был чистым:

  1. Извлечение значений из формы
  2. Убедитесь, что строки содержат только числа
  3. Преобразуйте значения из строк в фактические числа
  4. Убедитесь, что каждое число находится в допустимом диапазоне

Либо я выполняю преобразование типов внутри своего метода проверки и выводю ошибки типов так же, как сообщается об ошибке бизнес-правила (что я и хочу сделать, поскольку с точки зрения формы все ошибки проверки должны сообщаться одинаково). Мне это не нравится, потому что кажется неправильным изменять значения внутри метода проверки.

Или у меня есть два метода проверки: первый проверяет тип, но не изменяет данные, а второй предполагает, что типы верны, и выполняет проверку бизнес-правил, с функцией мутации между ними, которая выполняется только в том случае, если проверка типа прошла, и преобразует строки в числа. Мне нравится разделение, но это кажется немного сложным.

На самом деле я не очень хорошо отношусь ни к одному из этих вариантов. Как обычно решается эта проблема?

Ответ №1:

Хм … хороший вопрос.

Как насчет наличия класса FormDataMapping, который принимает строковые данные из формы, преобразует их в строго типизированные данные, а затем использует эти данные для инициализации нового экземпляра класса FormData. Класс FormData не сможет существовать в недопустимом состоянии, поэтому конструктор будет проверять все строго типизированные значения и выдавать исключение, если какое-либо значение недопустимо.

 // Responsible for mapping string data to an actual FormData instance
public class FormDataMapper
{
    public FormData CreateFormData(string percentText)
    {
        float percent = float.Parse(percent);

        return new FormData(percent);
    }
}

// Responsible for always being in a valid state
public class FormData
{
    public Percent { get; private set; }

    public FormData(float percent)
    {
        if(percent < 0 || percent > 100)
        {
            throw new ArgumentInvalidException("Percent must be between 0 and 100", "percent");
        }

        this.Percent = percent;
    }
}
  

Если вы планируете выполнять проверку javascript в реальном времени, это совсем другая проблема. Для этого у вас может быть отдельный этап проверки. Помните, что технически это просто реализация представления. Тот факт, что вы сообщаете пользователю, что они ввели неверные данные, не имеет никакого отношения к логике проверки вашего приложения. Вместо этого это просто удобство для пользователя (почти необходимое удобство в наши дни). 🙂