Теорія DDD звучить чудово. В ідеальному світі ми починаємо нові проекти (Greenfield), формуємо ідеальну команду, де кожен експерт володіє термінологією DDD, і створюємо бездоганну модель.
Але реальність, з якою ми стикаємося щодня, виглядає інакше:
У цій главі ми поговоримо про те, як застосовувати DDD в реальних, недосконалих умов. Як бути прагматичним, а не догматичним.
Перш ніж кидатися переписувати код, потрібно зрозуміти ландшафт. Згадайте стратегічні патерни з Частини I. Вони тут навіть важливіші, ніж у новому проекті.
Запустіть процес Knowledge Crunching (наприклад, EventStorming з Глави 12), щоб відновити втрачені знання про систему. Вам потрібно відповісти на питання:
Не намагайтеся рятувати все.
"Переписати з нуля" (Big Rewrite) — це майже гарантований провал. Замість революції, обирайте еволюцію.
Цей патерн названо на честь рослини, яка росте на дереві-хазяїні, поступово обвиває його і з часом замінює, залишаючи дерево вмирати всередині.
Алгоритм:
Якщо ви не можете виділити окремий сервіс, створіть "чисту зону" всередині моноліту. Це ваш новий Bounded Context.
Dictionary<string, object> UserDataclass Customer { Id id; Email email; }Іноді розплутувати залежності ("клубок спагетті") занадто дорого. Якщо вам треба розділити моноліт на два (наприклад, "Продажі" і "Логістика"), і код сильно зв'язаний:
Як перейти від Transaction Script (процедурний код) до Domain Model (ООП)? Робимо це крок за кроком.
Якщо у вас "Товсті Контролери" (вся логіка в API endpoint), винесіть логіку в Сервіси.
OrderController -> OrderService.
Це підготує ґрунт.
Це найдешевший спосіб підвищити якість коду.
Знайдіть string email, decimal amount, string currency.
Замініть на Email, Money.
Це додасть валідацію і логіку в самі дані.
Зараз ваш Order — це просто набір полів (DTO). Логіка лежить в OrderService.
Пересувайте методи в всередину класу Order.
service.CalculateTotal(order) -> order.CalculateTotal().
Принцип: Tell, Don't Ask. Не запитуйте дані у об'єкта, щоб щось з ними зробити. Скажіть об'єкту зробити це.
Коли логіка вже всередині об'єктів, визначте межі транзакцій.
Що має зберігатися разом? Order + OrderLine.
Захистіть інваріанти. Зробіть сетери приватними (private set). Змінюйте стан тільки через публічні методи з бізнес-назвами (AddItem, Confirm).
Якщо ви прийдете до менеджера і скажете: "Нам треба переписати систему на Агрегати, бо це правильно", вас виженуть. Бізнес не купує патерни. Бізнес купує вирішення проблем.
Іноді краще взагалі не використовувати терміни DDD. Не кажіть "Bounded Context". Кажіть "Модуль" або "Продукт". Не кажіть "Ubiquitous Language". Кажіть "Словник термінів". Просто робіть це. Використовуйте правильні імена в коді. Будуйте чисті моделі. Ваша робота — писати якісний код, і вам не завжди потрібен дозвіл на використання правильних інструментів.
DDD — це не срібна куля. Це набір інструментів для боротьби зі складністю.
Ніколи не застосовуйте DDD тільки заради того, щоб поставити галочку в резюме. Головна мета — створити програмне забезпечення, яке приносить цінність і яке можна підтримувати роками.
Кінець. Дякуємо, що були з нами у цій подорожі світом Domain-Driven Design!
Глава 12. EventStorming
Ми розглянули безліч інструментів DDD для аналізу та моделювання. Але як застосувати їх, коли ви працюєте не один, а з групою людей, які мають різний рівень розуміння бізнесу та технологій? Тут на сцену виходить EventStorming.
01. Магія Стрімінгу: Що відбувається, коли ви натискаєте "Play"