Я работаю над системой, которая позволяет администраторам определять формы, содержащие поля. Затем определенные формы используются для ввода данных в систему. Иногда формы заполняются человеком через графический интерфейс, иногда форма заполняется на основе значений, сообщаемых другой системой.
Для каждого поля администратор может определить правило проверки, которое ограничивает допустимые значения для поля. Правила проверки могут быть любыми: от «значение, введенное в поле должно быть истинным или ложным» до «значение, введенное в поле, должно существовать в столбце A таблицы B в базе данных». Администратор может в любое время изменить Правило валидации для Поля.
В этом сценарии, что, по вашему мнению, является наиболее подходящим местом для проверки правильности заполнения каждого поля? В настоящее время я имею в виду два основных подхода:
Вариант № 1: проверка в доменной модели
Каждый объект поля будет содержать правило валидации, указанное администратором. Объекты Field также имеют ссылку на IValidator. Когда делается попытка установить значение поля, поле передает заданное значение и правило проверки в IValidator. Если данное значение недопустимо, исключение ValidationException будет выброшено и соответствующим образом обработано в графическом интерфейсе / интерфейсе другой системы.
Плюсы:
- Надежная защита от случайного присвоения Полям значений, которые нарушают Правило валидации
Минусы:
Уровень доступа к данным должен иметь возможность обходить проверку и создавать поля, которые нарушают текущее правило проверки. Несмотря на то, что администратор изменил правило проверки для поля, нам все еще нужно иметь возможность создавать объекты поля на основе старых данных, например, при визуализации формы, которая была заполнена несколько лет назад. Это может быть решено путем сохранения текущего правила проверки всякий раз, когда мы сохраняем поле.
В этом проекте модель поля имеет косвенную связь с уровнем доступа к хранилищу данных / репозиторием через IValidator. Внедрение сервисов / репозиториев в доменные модели, как правило, не одобряется .
Вариант № 2: проверка в сервисе
Постарайтесь обеспечить, чтобы все попытки установить значение поля проходили через службу, которая обеспечивает соблюдение правила проверки. Если правило проверки нарушено, выведите исключение ValidationException.
Конечно, Уровень доступа к данным не будет использовать Сервис при создании объектов Поля, которые ранее были сохранены в БД.
Плюсы:
Не нарушает мышление «не вводить сервисы / репозитории в ваши доменные модели».
Нет необходимости сохранять текущее правило проверки при сохранении поля. Служба может просто найти текущее правило проверки для поля; при просмотре данных истории значение поля не изменится.
Минусы:
- Нет гарантии, что вся логика, которая должна использовать Сервис для установки значения поля, на самом деле делает это. Я вижу это как главный недостаток; все, что кажется, нужно, чтобы кто-то написал «thisField.setValue (thatField.getValue ())», и правило проверки thisField может быть нарушено, и никто не будет мудрее. Это может быть потенциально смягчено, если убедиться, что значение поля совпадает с правилом проверки, когда уровень доступа к данным собирается сохранить поле.
В настоящее время я предпочитаю вариант № 1, а не вариант № 2, главным образом потому, что я рассматриваю это как бизнес-логику и чувствую, что вариант № 2 представляет больший риск введения неверных данных в систему. Какой вариант вы предпочитаете, или есть другой дизайн, который подходит к этому сценарию лучше, чем два описанных варианта?
Редактировать (сложность проверок)
Случаи проверки, которые возникли на данный момент, относительно просты; значение поля должно быть, например, числовым, датой, датой со временем или существующим значением в столбце базы данных. Тем не менее, я подозреваю, что сложность постепенно увеличивается со временем. Например, решение для проверки должно быть построено с учетом интернационализации - такие вещи, как Dates, могут вводиться в синтаксисе, зависящем от локали.
Сейчас я решил перейти к варианту № 1, стараясь не назначать слишком много обязанностей для модели предметной области. Те, кто сталкивается с подобной ситуацией, могут также захотеть проверить связанные вопросы Проверка и авторизация в многоуровневой архитектуре и Проверка ввода данных - Где? Как много? ,