Я занурився в концепцію дизайну, керованого доменом (DDD), і виявив деякі принципи дивними, особливо стосовно ізоляції доменної та стійкої моделі. Ось моє основне розуміння:
- Служба на рівні додатків (надає набір функцій) запитує доменні об’єкти із сховища, яке йому потрібно для виконання своєї функції.
- Конкретна реалізація цього сховища отримує дані з сховища, для якого воно було реалізовано
- Служба повідомляє об'єкту домену, який інкапсулює ділову логіку, виконувати певні завдання, які змінюють його стан.
- Служба повідомляє сховищу зберігати модифікований об’єкт домену.
- Репозиторію потрібно віднести об’єкт домену назад до відповідного представлення у сховищі.
Тепер, з огляду на вищенаведені припущення, наступне здається незручним:
Оголошення 2 .:
Здається, що модель домену завантажує весь об’єкт домену (включаючи всі поля та посилання), навіть якщо вони не потрібні для функції, яка його вимагала. Завантаження повністю може бути навіть неможливим, якщо на них посилаються інші об’єкти домену, якщо ви також не завантажите ці доменні об'єкти та всі об'єкти, на які вони посилаються, і так далі тощо. Приходить на думку ледаче завантаження, що, однак, означає, що ви починаєте запитувати об’єкти свого домену, за що в першу чергу повинна відповідати сховище.
Враховуючи цю проблему, "правильний" спосіб завантаження об'єктів домену, здається, має виділену функцію завантаження для кожного випадку використання. Ці виділені функції потім завантажуватимуть лише ті дані, які вимагаються випадком використання, для якого вони були розроблені. Ось де грає незграбність: По-перше, я повинен був би підтримувати значну кількість функцій завантаження для кожної реалізації сховища, і доменні об’єкти опиняться в неповних станах, що перебувають null
у своїх полях. Останнє технічно не повинно бути проблемою, оскільки якщо значення не було завантажене, воно не повинно вимагати функціоналів, які його вимагали в будь-якому випадку. І все-таки це незручно та потенційно небезпечно.
Об'ява 3 .:
Як доменний об’єкт перевірить обмеження унікальності при побудові, якщо він не має уявлення про сховище? Наприклад, якби я хотів створити новий User
з унікальним номером соціального страхування (який вказаний), найдавніший конфлікт виникне при проханні сховища зберегти об'єкт, тільки якщо в базі даних є обмеження унікальності. В іншому випадку я можу шукати User
відповідне соціальне забезпечення та повідомити про помилку, якщо воно існує, перш ніж створити нове. Але тоді перевірки обмежень житимуть у службі, а не в об’єкті домену, де вони належать. Я щойно зрозумів, що об’єктам домену дуже добре дозволено використовувати (вводити) сховища для перевірки.
Оголошення 5 .:
Я сприймаю відображення об’єктів домену в резервній пам’яті як процес, що є інтенсивним роботою, порівняно з тим, щоб доменні об’єкти безпосередньо змінювали підкладені дані. Безумовно, це важлива передумова від'єднання конкретної реалізації зберігання від доменного коду. Однак чи дійсно це стоїть з такою високою ціною?
У вас, мабуть, є можливість використовувати інструменти ORM, щоб зробити картування для вас. Вони часто вимагають від вас спроектувати доменну модель відповідно до обмежень ORM, або навіть запровадити залежність від домену до інфраструктурного рівня (наприклад, використовуючи примітки ORM в об'єктах домену). Також я читав, що ORM вводять значні обчислювальні витрати.
Що стосується баз даних NoSQL, для яких навряд чи існують поняття, подібні до ORM, як ви відстежуєте, які властивості змінювались у моделях домену save()
?
Редагувати : Також для того, щоб сховище отримало доступ до стану об’єкта домену (тобто значення кожного поля), об’єкт домену повинен виявити його внутрішній стан, який порушує інкапсуляцію.
В загальному:
- Куди піде транзакційна логіка? Це, безумовно, специфіка стійкості. Деякі інфраструктури зберігання можуть взагалі не підтримувати транзакції (як сховища макетів в пам'яті).
- Чи потрібно для об'ємних операцій, що змінюють декілька об'єктів, завантажувати, змінювати та зберігати кожен об'єкт окремо для того, щоб перейти через інкапсульовану логіку перевірки об'єкта? Це протилежне виконанню одного запиту безпосередньо на базі даних.
Буду вдячний за певні роз’яснення на цю тему. Чи правильні мої припущення? Якщо ні, то який правильний спосіб вирішити ці проблеми?