Чи "Інверсія контролю" сприяє "анемічній моделі домену"?


32

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

Я бачив проекти, написані іншими розробниками, які використовують "Інверсію контролю", і вони завжди "анемічні".

Оскільки "Анемічна модель домену" є антидіаграмою, чи можна використовувати IoC та Rich Domain? Чи є їхні хороші приклади, проекти з відкритим кодом, які роблять це?


Думаю, нам потрібно переглянути конкретні приклади вашого конкретного випадку, щоб допомогти.
Мартійн Вербург

1
Вибачте, я мав на увазі фрагменти коду :)
Martijn Verburg,

Відповіді:


11

Для початку: DI та IoC не є синонімами. Мені шкода, але я мушу це зазначити (мені здається, ти думаєш, що вони є).

Що стосується вашого запиту ... Ну, введення залежностей - це лише інструмент. Як ви збираєтеся використовувати цей інструмент - це зовсім окрема річ. Існують також інші інструменти (схеми дизайну), які можуть доповнити проблему. Наприклад, я вважаю, що широке прийняття шаблону MVC є одним з ключових компонентів для формування антидіапазону моделі Anemic Domain Model: контролери (у більш простих програмах, у складніших, які були б додатковими службовими рівнями) беруть на себе відповідальність за перевірку правил бізнесу , примусово застосовуючи їх, а також перетворюючи об'єкти БД у щось корисне, тоді як бізнес-шар перетворюється на простий рівень доступу до даних, який є простим ORM з відображенням один на один, до об'єктів бази даних.

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


Я додам до цього, що, можливо, ви могли б заглянути в DDD-підхід, який підтримували Ерік Еванс та ін.
Мартійн Вербург

1
Я читав книгу Еріка Еванса. Це добре для загальної методології та всюдисущої мови, але дещо бракує прикладів у реальному світі.
Mag20

Дякуємо, що вказали на різницю між DI та IoC. Я думаю, що це питання більше стосувалося IoC, ніж DI. Змінив питання, щоб це відобразити.
Mag20

З мого досвіду роботи з рамками / контейнерами DI (Spring DI, CDI, Unity), вони насправді не дозволяють вам створити "правильну модель домену", що для мене означає, що розробникам не слід обмежувати використання справжніх (тобто, стаціонарних) об'єктів . Але DI не дуже підтримує це.
Rogério

8

Більшість програм (якщо не всі) є сукупністю проблем інфраструктури та домену. Коли ви досягнете певного рівня складності, вам буде легше керувати, якщо домен відокремлений від інфраструктури, щоб було простіше міркувати і еволюціонувати самостійно.

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

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

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


7

Перейдіть до джерела. Почніть з твору Фаулера на моделях Anemic Domain . Він наводить дизайн Еріка Евана, керований доменом як приклад належної практики. Вихідний код для цього знаходиться тут . Завантажте його.

Зауважте, що він використовує Інверсію управління (пошук @Autowired), має класи обслуговування (BookingService) та класи "бізнес-процесів" (наприклад, ItineraryUpdater).

Оригінальна стаття Фоулера починає слід до прикладу, який ви шукаєте.


Цей зразок програми насправді не відповідає DDD, як описано в книзі. Конкретне протиріччя з книгою полягає в тому, що вона цілком порушує поняття "інфраструктура", дозволяючи їй містити доменний код; наприклад, VoyageRepositoryHibernateклас, який був розміщений в інфраструктурному шарі, але насправді залежить від доменного шару.
Rogério

Так, у книзі на сторінці 73 сказано, що інфраструктурний рівень знаходиться «нижче» доменного рівня і «він не повинен мати спеціальних знань про домен, який він обслуговує». Це просто ніколи не мало для мене сенсу. Розглянемо проект, який має дві реалізації VoyageRepository: VoyageRepositoryHibernate та клас VoyageRepositoryJDBC. Їх реалізація обов'язково дуже різна, а технологія специфічна. Вони належать до доменного шару? Або інфраструктурний рівень? У нашому коді, згідно з книгою, ми робимо це назад: інфраструктурний рівень може посилатися на доменний шар, але не навпаки.
jamie

Вони належать до доменного шару, так. Реалізація на основі JDBC міститиме код SQL, прив'язаний до таблиць і стовпців у базі даних додатків, які є специфічними для домену. Введення будь-якого коду, що стосується домену або програми, в інфраструктурний рівень є просто неправильним, оскільки "інфраструктурний код" повинен використовуватися лише для вирішення технічних проблем, і він (в ідеалі) повинен бути повністю використаний для різних додатків та доменів. Рішення наявності коду "низького рівня" (наприклад, SQL) у доменному шарі полягає не в тому, щоб повністю перемістити його, а реалізувати його над кращою інфраструктурою, наприклад ORM.
Rogério

Для мене реалізація збереження (MyDomainObject foo) - суто технічна проблема. YMMV.
jamie

Тільки якщо це не призведе до того, що ви порушите основне правило шаруватої архітектури: нижній шар не може залежати від вищого шару. Отже, якщо ви реалізували save(foo)код, який підлягає зміні при зміні моделі домену (наприклад, якщо до нього додається новий атрибут MyDomainObject), він повинен (за визначенням) належати до доменного шару; інакше ви просто не можете говорити про те, щоб мати "шари" більше.
Rogério

7

чи можна використовувати IoC та Rich Domain? Чи є їхні хороші приклади, проекти з відкритим кодом, які роблять це?

Я припускаю, що ви маєте на увазі DI замість IoC, а проект, над яким ви працювали, використовує контейнер DI на зразок Spring. IoC має два основних аромати: DI і Locator. Я не бачу, чому модель «Локатор» повинна бути проблемою, тож давайте зосередимось на DI.

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

Ось чому ви не хочете дозволяти контейнеру DI керувати об'єктами вашого домену. Але якщо ви створюєте об’єкти вручну (з новими), ви не можете ін'єктувати інші об’єкти у ваші доменні об’єкти. (Залишаючи потенційні робочі місця з ручним електропроводкою убік.) Оскільки ці ін'єкції потрібні для заміни реалізацій на інші, ви не можете замінити функціональність об'єктів, що мають багатий домен, використовуючи DI. Отже, ви не хочете розміщувати функціональність в об’єктах домену, інакше ви втратите функції DI.

Я не бачу, як може працювати гіпотетичний контейнер DI, який не керує вашими об'єктами, і жодна з існуючих реалізацій цього не дозволяє. Тому справедливо стверджувати, що DI покладається на управління об'єктами. Тому завжди буде спокушати вас розділити потенційні об’єкти Rich Domain на один анемічний клас та один або кілька класів скриптів транзакцій.


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