Я працюю над системою, яка дозволяє адміністраторам визначати форми, які містять поля. Визначені форми потім використовуються для введення даних у систему. Іноді Форми заповнюються людиною через GUI, іноді Форма заповнюється на основі значень, повідомлених іншою системою.
Для кожного поля адміністратор може визначити правило перевірки, яке обмежує допустимі значення для поля. Правила перевірки можуть бути будь-якими, від "значення, введене в поле повинно бути істинним або помилковим", до "значення, введене в поле, повинно існувати у колонці таблиці таблиці В в базі даних". Адміністратор може в будь-який час змінити Правило перевірки поля.
У цьому сценарії, що, на вашу думку, є найбільш підходящим місцем для перевірки правильності заповнення кожного поля? На даний момент маю на увазі два основні підходи:
Варіант №1: Підтвердити модель домену
Кожен об'єкт Field містив би правило перевірки, визначене адміністратором. Об'єкти поля також мали б посилання на IValidator. Коли робиться спроба встановити значення поля, поле передасть задане значення та правило перевірки IValidator. Якщо задане значення недійсне, ValidationException буде викинуто і відповідним чином обробляється в GUI / інтерфейсі для іншої системи.
Плюси:
- Сильний захист від випадково присвоєних полів значень, що порушують Правило перевірки
Мінуси:
Шар доступу до даних повинен бути в змозі обійти валідацію та побудувати поля, що порушують поточне правило перевірки. Незважаючи на те, що адміністратор змінив Правило перевірки для поля, нам все-таки потрібно мати можливість будувати об’єкти поля на основі старих даних, наприклад, під час надання форми, заповненої років тому. Це потенційно може бути вирішено, зберігаючи поточне правило перевірки, коли ми зберігаємо поле.
У цій конструкції модель Field має непряме посилання на рівень / сховище доступу до даних через IValidator. Введення послуг / репозиторіїв до доменних моделей, здається, зазвичай нахмуриться .
Варіант №2: перевірка в сервісі
Постарайтеся переконатися, що всі спроби встановити значення поля проходять через службу, яка забезпечує виконання правила перевірки. Якщо правило перевірки порушено, киньте ValidationException.
Звичайно, рівень доступу до даних не використовував би Сервіс під час створення об'єктів Field, які раніше зберігалися в БД.
Плюси:
Не порушує мислення "не вводьте служби / сховища у ваші доменні моделі".
Не потрібно зберігати поточне правило перевірки під час збереження поля. Служба може просто знайти поточне правило перевірки для поля; при перегляді даних історії значення Поля не буде змінено.
Мінуси:
- Ніякої гарантії, що вся логіка, яка повинна використовувати Сервіс для встановлення значення поля, насправді так і робить. Я бачу це як головний недолік; все, що, здається, береться за те, щоб хтось написав "thisField.setValue (thatField.getValue ())", і Правило перевірки цього FiFi може бути порушено, без того, щоб хтось мудріший. Це потенційно може бути зменшене, гарантуючи, що значення поля збігається з правилом перевірки, коли рівень доступу до даних збирається зберігати поле.
В даний час я віддаю перевагу варіанту №1 над варіантом №2, головним чином тому, що я сприймаю це як ділову логіку і вважаю, що варіант №2 створює більший ризик введення поганих даних у систему. Який варіант ви віддаєте перевагу, чи є інший дизайн, який краще відповідає цьому сценарію, ніж два описані варіанти?
Редагування (Складність перевірок)
Випадки перевірки, що з’явилися зараз, відносно прості; Значення поля повинно бути, наприклад, числовим, датою, датою з часом або бути наявним значенням у стовпці бази даних. Однак я підозрюю, що складність з часом поступово збільшуватиметься. Наприклад, рішення для перевірки потрібно будувати з урахуванням інтернаціоналізації - такі речі, як Дати, можуть бути введені в синтаксис, характерний для локальної мови.
Наразі я вирішив перейти до Варіанту №1, намагаючись подбати про те, щоб не покласти занадто багато обов'язків до Доменної моделі. Особи, які стикаються з подібною ситуацією, можуть також захотіти перевірити відповідні питання Валідація та авторизація у багатошаровій архітектурі та перевірка введення даних - Де? Скільки? .