Когда я использовал IoC Container в моем последнем проекте, я получил анемичные сущности и большую часть своей бизнес-логики в сервисах без сохранения состояния.
Я видел проекты, написанные другими разработчиками, которые используют «Inversion of Control», и они всегда «анемичны».
Поскольку «Модель анемичного домена» является анти-шаблонной, возможно ли использовать IoC и Rich Domain? Есть ли у них хорошие примеры, проекты с открытым исходным кодом, которые делают это?
dependency-injection
Mag20
источник
источник
Ответы:
Для начала: DI и IoC не являются синонимами. Извините, но я должен указать на это (мне кажется, вы так думаете).
Что касается вашего запроса ... Ну, Dependency Injection - это всего лишь инструмент. То, как вы собираетесь использовать этот инструмент, совершенно отдельная вещь. Есть и другие инструменты (шаблоны проектирования), которые могут усугубить проблему. Например, я считаю, что широкое внедрение шаблона MVC является одним из ключевых компонентов формирования анти-шаблона Anemic Domain Model: контроллеры (в более простых приложениях, в более сложных, которые могут быть дополнительными уровнями обслуживания) берут на себя ответственность за проверку бизнес-правил усиливая их, а также превращая сущности БД во что-то полезное, тогда как бизнес-уровень превращается в простой уровень доступа к данным, который представляет собой простой ORM с однозначным сопоставлением сущностей базы данных.
Конечно, именно так вы разрабатываете свое приложение - вы можете создать правильную модель предметной области, если хотите, и все эти IoC, DI, MVC не останавливают вас. Что может остановить тебя, так это твоя команда. Вам как-то нужно убедить их использовать правильный путь, и это может быть сложно, так как многие разработчики программного обеспечения не имеют достаточного архитектурного опыта.
источник
Большинство (если не все) приложения представляют собой сочетание инфраструктуры и проблем домена. Когда вы достигнете определенного уровня сложности, вам будет легче управлять, если домен будет отделен от инфраструктуры, чтобы его было легче рассуждать и развиваться независимо.
Конечно, модель домена все еще должна взаимодействовать с остальной частью системы, и обычно это происходит со службами без сохранения состояния (которые являются частью домена), в которые встраиваются проблемы инфраструктуры (например, доступ к базе данных). Использование контейнера IoC не удаляет эту зависимость, он перемещает свою конфигурацию в отдельную область, что снова упрощает анализ и поддержку.
Объекты хранят состояние и должны нести ответственность за бизнес-правила. Если ваши службы применяют все инварианты и другие бизнес-правила, вероятно, логика не в том месте.
Теперь, если вы располагаете логикой в нужных местах и при этом по-прежнему получаете сервисы, которые являются не более чем обертками вокруг объектов инфраструктуры и сущностей, которые являются просто пакетами свойств, тогда весьма вероятно, что домен не достаточно сложен, чтобы оправдать накладные расходы на собственную модель. Почти все, что вы прочтете о DDD, будет содержать заявление об отказе от ответственности, которое на самом деле предназначено только для сложных доменов, но об этом слишком часто забывают.
источник
Перейти к источнику. Начните с статьи Фаулера о моделях анемичных доменов . Он ссылается на управляемый доменом дизайн Эрика Эвана как пример хорошей практики. Исходный код для этого здесь . Загрузить.
Обратите внимание, что он использует Inversion of Control (поиск по @Autowired), имеет классы обслуживания (BookingService) и классы «бизнес-процессов» (например, ItineraryUpdater).
Оригинальная статья Фаулера начинается с примера, который вы ищете.
источник
VoyageRepositoryHibernate
класс, который был помещен в уровень инфраструктуры, но на самом деле зависит от уровня домена.save(foo)
код, который может изменяться при изменении модели домена (например, если в него добавлен новый атрибутMyDomainObject
), то он должен (по определению) принадлежать слою домена; в противном случае вы просто не можете больше говорить о наличии «слоев».Я предполагаю, что вы имеете в виду DI вместо IoC, а в проекте, над которым вы работали, используется контейнер DI, такой как Spring. IoC имеет два основных варианта: шаблон DI и шаблон Locator. Я не понимаю, почему шаблон локатора должен быть проблемой, поэтому давайте сосредоточимся на DI.
Я не думаю, что это возможно, или, по крайней мере, было бы очень непрактично. Основной аспект DI-контейнеров заключается в том, что они контролируют создание объектов, когда они внедряют их в другие («управляемые объекты»). Набор управляемых объектов, который действует во время выполнения проектов, не зависит от того, какие элементы домена существуют в вашем проекте, но зависит от того, как объекты связаны, и какие области (синглтон, прототип) назначены им.
Вот почему вы не хотите, чтобы DI-контейнер управлял вашими объектами домена. Но если вы создаете объекты вручную (с помощью new), вы не можете добавить другие объекты к объектам вашего домена. (Оставляя в стороне потенциальные обходные пути с ручным подключением.) Поскольку эти внедрения необходимы для замены реализаций другими, вы не можете заменить функциональность объектов расширенного домена с помощью DI. Следовательно, вы не захотите размещать функциональность в доменных объектах, иначе вы потеряете функции DI.
Я не понимаю, как может работать гипотетический DI-контейнер, который не управляет вашими объектами, и ни одна из существующих реализаций не позволяет этого. Поэтому справедливо утверждать, что DI полагается на управление объектами. Поэтому он всегда будет искушать вас разделить потенциальные объекты Rich Domain на один анемичный класс и один или несколько классов сценариев транзакций.
источник