DDD - Чи є анемічна модель домену антипаттерна? Чи повинні ми використовувати багаті доменні моделі? [зачинено]


11

Анемічна модель домену дуже давно критикувалася Евансом і Фаулером , оскільки, очевидно, це суперечить об'єктно-орієнтованим принципам тощо. Спільнота DDD чітко узгоджується з цими твердженнями.

Однак останніми роками з'явилися суперечливі голоси, які стверджують, що це зовсім не антипатерн, і що це приклад дотримання принципів SOLID.

Я стільки років працюю, використовуючи Spring Framework. Кожен проект у кожній компанії завжди мав рівень обслуговування, що містить логіку бізнесу, використовуючи сховища, які працюють на анемічних моделях (суб'єкти JPA). Крім того, більшість зразків, навіть офіційні з весняних хлопців, демонструють такий спосіб роботи.

Мої запитання: чи анемічна модель домену все ще вважається антипатернією? Чи ми всі робили речі (щодо DDD) неправильно? Ви не вважаєте, що наявність моделей Rich Domain порушує принципи SOLID?


2
" чи анемічна модель домену все ще вважається антипатрійною? ". По деяких так. Інші, в тому числі, я вважаю це переважним способом написання коду більшу частину часу, але якщо RDM вам підходить, використовуйте його. Тож голосування, щоб закрити це як суто засноване на думці.
Девід Арно

1
Це було б фантастичним питанням для дискусійно-дискусійного форуму; але наразі не існує авторитетної відповіді. Ми віддаємо перевагу питанням, на які можна відповісти, а не просто обговорювати.
VoiceOfUnreason

Відповіді:


9

ADM - хороший зразок для вирішення розподілених сервісів таких мікросервісів. Він підходить для багатьох сучасних бізнес-кейсів.

Подумайте, чи є у нас об’єкт Order Order. За допомогою підходу OOP ми додамо Order.Purchase () Order.Cancel () і т.д.

Але якщо у нас є розподілена система, з програмами, які просто одне, тобто доступ до списку замовлень і придбання кожного по черзі, або отримання списку замовлень і скасування кожного по черзі, то якщо обидва Методи на одному об'єкті не робить сенс. Ми повинні мати два домени або обмежені контексти:

PurchaseSystemOrder.Purchase()

і

CancelSystemOrder.Cancel();

Єдине, чим би поділилися ці об'єкти, - це структура даних властивостей.

Коли ви додаєте все більше мікросервісів, ви отримуєте десятки типів замовлення. Він більше не має сенсу говорити про ордена в якості об'єкта домену, незважаючи на те, його ж концептуальному порядку , який обробляється усіма цими системами.

Має більше сенсу мати анемічну модель «Замовлення», яка просто інкапсулює лише дані та відповідно перейменовує ваші послуги:

PurchaseService.Purchase(Order order)

Тепер ми можемо поговорити про замовлення ще раз, і ми можемо додавати будь-які нові послуги, які ми придумаємо для обробки, не впливаючи на інші розгорнуті в даний час послуги.

Фаулер і Ко походять з монолітної системи, у їхньому світі підхід ADM означатиме єдину програму, в якій всі ці окремі сервіси створені в пам'яті, і OrderDTO передається навколо і мутується. Це було б набагато гірше, ніж розміщення методів на багатої моделі замовлення.

Але в розподіленій системі є багато програм, кожна з яких вимагає лише одного методу замовлення та виконує його на декількох замовленнях, завантажуючи кожне, запускаючи метод і потім відкидаючи його. Для цього потрібна лише одна Служба та потік об'єктів даних.

Повноцінно використовувати насичену модель, турбуватися про вимоги та залежності всіх Методів лише для виклику однієї, а потім відкидання об'єкта майже одразу безглуздо.

Плюс до зміни одного з методів вимагатиме оновлення всіх розподілених компонентів, оскільки всі вони залежать від моделі Rich за своєю логікою.

У моїх кодових базах немає місця для речей, які їм не потрібні


4
Я прихильнився тому, що вважаю, що DDD особливо добре підходить до мікропослуг саме завдяки концепції обмеженого контексту. Я думаю, що проблема вашої відповіді полягає в тому, що концепція і клас замовлення будуть однаковими для кожної мікро-служби, але я думаю, що це не потрібно і не є точним.
RibaldEddie

Я не погоджуюся, ADM може бути DDD, якщо ви зателефонуєте на ваш PurchaseService CashRegister і зробите його частиною вашої мови домену
Ewan

чи можете ви докладно? Я завжди думав, що YMMV, коли ADM та DDD знаходяться в твердій базі коду J2EE або .NET C # MVC EF.
RibaldEddie

Що я маю на увазі, що обмежений контекст Order, PurchaseSystemOrder.Purchase () буде майже ідентичним коду CashRegister.Purchase (Замовлення замовлення) - це лише зміна імені у вашій мові домену. Модель багатого домену означає наявність методів купівлі та скасування в одному класі.
Еван

1
@RibaldEddie, На думку товщини книги "jaScript, хороші частини", я пропоную це зображення як (не зовсім серйозний) аргумент проти використання DDD для впровадження мікросервісів;)
Девід Арно,

3

SOLID і DDD є ортогональними один для одного, тобто вони дійсно йдуть в різні сторони один від одного. Не слід говорити, що один звик до виключення іншого, оскільки вони можуть і повинні, ймовірно, існувати разом в одній базі коду.

Моделі анемічних доменів стають анти-шаблоном лише після того, як у вашої проблемної домени спостерігається багато поведінки і у вас є сотні методів обслуговування з великою кількістю вкладеної логіки або залежностей, де методи сервісного рівня повинні викликати інші методи службового рівня, щоб зробити що-небудь зробленим.

DDD - відмінна парадигма для мікропослуг через концепцію обмеженого контексту .

Остерігайтеся спокуси бачити інфраструктурний код як частину вашого домену. Інфраструктурний код - це все, що ви самі не написали, або щось, що поєднується з рамкою або бібліотекою, яка взаємодіє із сторонніми системами. Підключення до бази даних, поштові розсилки SMTP, бібліотеки ORM, час роботи сервера додатків, все те, що є ресурсом, є інфраструктурою, і ви не повинні включати його та не залежати від нього у своєму домені, якщо ви можете цього уникати.

Принципи SOLID - це набір концепцій OOP загального призначення, які можна використовувати для покращення коду OOP. Ви можете написати хорошу базу даних DDD, використовуючи їх.


Щодо відокремлення інфраструктурного коду від домену. Досі я вважав, що об'єкти JPA є моїм доменом, маючи такі рівні додатків: контролер -> сервіс -> сховище -> домен (об'єкти JPA). Який би був правильний (або один із правильних) способів його моделювання відповідно до вашої точки зору? Щось на кшталт: контролер -> багата модель -> x? Як і де я мав би справу з транзакцій? А що з JPA Mapping? Чи не доведеться нам дублювати нашу насичену модель з відокремленими об'єктами JPA?
кодепендент

Сутність JPA - це звичайний старий об'єкт Java. Відображення є частиною інфраструктури, але сам клас не повинен бути. Якщо ви вирішите трактувати його як частину інфраструктури, тоді вам слід розглянути його як об'єкт передачі даних, який використовується на Фабриці чи сховищі для створення об'єкта домену.
RibaldEddie

1

Багатий домен приємно, коли робиться добре. Кошмар, коли ні. Анемічний домен завжди поганий. Але це знайомий комфортний вид поганого.

Якщо вам потрібен анемічний домен, ви вибрали неправильну мову, коли вибрали мову загального призначення. Мови четвертого покоління спеціалізуються навколо конкретного використання. Якщо анемія досить добра, їх використання полегшило б ваше життя.

Багато фреймворків проникають у мовний простір, поки ви вже не зможете рекламувати роботу як роботу Java. Це робота Java / Spring. Те, що вони роблять, окрім того, щоб ви залежали від них, - це перетворити мову загального призначення на негідну форму мови четвертого покоління.

Це найкраща практика чи анти-модель? Добре, що ви боса в основному просто переймаєтесь тим, чи можете ви найняти людей для роботи над базою коду. Тож якщо нам доведеться робити вигляд, що ми використовуємо мову загального призначення, щоб найняти людей, яких ми бажаємо.

Якщо все гаразд із цим, то добре. Ти, звичайно, не єдиний.

Але не кажіть мені, як це має бути. Не кажіть мені, що вона робить для мене щось більше, ніж це є. Я знаю, як жити без цього. Я знаю, як його витіснити, тому від цього залежить лише кілька речей. Якщо ви просите мене поступитися і дозволити йому взяти на себе все тільки тому, що боротися з цим важко, то так, я думаю, це погано.

У моїй кодовій базі немає місця для речей, які йому не потрібні.

Що стосується SOLID та інших принципів дизайну, я можу значною мірою слідувати цим навіть у анемічній області. Якщо їх дотримання не спричиняє, це призводить до різного роду проблем.


Я вдячний за вашу відповідь і абсолютно згоден з тим, що деякі рамки, такі як Spring або JPA-Hibernate, підкорили пейзаж Java. Однак також незаперечно, що вони запропонували купу передового досвіду та спрощень, до яких Java (JEE) взагалі не зверталася або зробила неправильно. Я дуже захоплений DDD і хотів би зрозуміти всі принципи, які вони розповідають. У вашому досвід, які найкращі платформи / мови / рамки для роботи з чистими програмами DDD (з моделями Rich Domain)? Будь-який хороший зразок Github ви знаєте? Як ви кажете, я хочу робити все добре, а не відповідати поганій практиці.
залежно від коду

Тут ми не робимо рекомендацій щодо ресурсів. Але я вважаю, що належний інфраструктурний рівень, який стосується рамки, означає, що ви можете використовувати будь-який тип, який вам подобається. Просто ставитесь до них, як до бібліотеки. Зберігайте знання про них поза доменом. Крім того, не покладайтеся на магію. Не встояйте перед бажанням використовувати речі, які ви не змогли зробити самі. Тому що вам може знадобитися якийсь день.
candied_orange

Повернення до початкової точки. Що щодо принципів SOLID? Моделі багатого домену беруть на себе багато обов'язків, наполегливість (JPA), ділову логіку (доводиться мати справу з транзакцій) і т.д. Звучить також простіше тестування. Що ж тоді в цьому поганого?
кодекс залежно

Головне, ви починаєте робити вибір дизайну на основі системних потреб, а не семантичних потреб. Його тонка, легко ігнорувати, вартість не очевидна і важко виправдати виправлення. Коротше кажучи, це як стверджувати, що лінії електропередач слід закопувати, а не на виборчих дільницях. Після того, як люди звикнуть до чужої альтернативи, це, швидше за все, не зміниться. Навіть коли урагани вибивають силу.
candied_orange

1
Я збирався дати вам користь від сумнівів у вашій заяві, що "Багатий домен - це добре, коли робиться добре. Кошмар, коли ні". Можливо, я просто ніколи не бачив, щоб це було добре, але тоді ви заявляєте дурниці, що "анемічний домен завжди поганий". Дурницькі дурниці роблять вашу відповідь нікчемною. -1
Девід Арно
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.