Ответ Дмитрия указывает на некоторые хорошие вещи, которые нужно искать.Часто / легко вы попадаете в свой сценарий, когда данные перемещаются от БД к GUI через разные уровни.
Меня вдохновил простой совет Джимми Нильссона "Объекты-ценности, объекты-ценности и другие объекты-ценности".Часто люди, как правило, сосредотачиваются на существительных и моделируют их как сущность.Естественно, у вас часто возникают проблемы с поиском поведения DDD.Глаголы легче ассоциировать с поведением.Хорошо, чтобы эти глаголы появлялись в вашем домене как объекты Value.
Некоторые рекомендации, которые я использую для себя при разработке домена (должны сказать, что для создания богатого домена требуется время, часто несколькоитерации рефакторинга ...):
- Свернуть свойства (получить / установить)
- Использовать как можно больше объектов-значений
- Предоставлять как можно меньше.Сделайте ваши доменные агрегаты интуитивно понятными.
Не забывайте, что ваш домен может быть богатым, выполняя валидацию.Только ваш домен знает, как совершить покупку, и что требуется.
Ваш домен также должен отвечать за проверку, когда ваши сущности переходят из одного состояния в другое состояние (проверки рабочего процесса).
Я приведу несколько примеров: Вот статья, которую я написал в своем блоге, касающаяся вашей проблемы с анемичным доменом. http://magnusbackeus.wordpress.com/2011/05/31/preventing-anemic-domain-model-where-is-my-model-behaviour/
Я также могу порекомендовать статью в блоге Джимми Богарда о проверке сущностей и использованииШаблон валидатора вместе с методами расширения.Это дает вам свободу проверять инфраструктурные объекты, не загрязняя ваш домен: http://lostechies.com/jimmybogard/2007/10/24/entity-validation-with-visitors-and-extension-methods/
Я с большим успехом использую События домена Udi.Вы также можете сделать их асинхронными, если считаете, что ваша служба может выйти из строя.Вы также заключаете его в транзакцию (используя платформу NServiceBus).
В вашем первом примере (просто мозговой штурм сейчас, чтобы заставить наш разум больше думать о ценностных объектах).
- Ваш
MusicService.AddSubscriber(User newUser)
Служба приложений получает звонок от ведущего / контроллера / WCF с новым пользователем.Сервис уже получил IUserRepository
и IMusicServiceRepository
, введенный в ctor. - Музыкальный сервис "Spotify" загружается через IMusicServiceRepository
- Сущность
musicService.SignUp(MusicServiceSubscriber newSubsriber)
Метод принимает объект Value MusicServiceSubscriber
.Этот объект Value должен принимать User и другие обязательные объекты в ctor (объекты значения являются неизменяемыми).Здесь вы также можете разместить логику / поведение, например дескриптор subscriptionId и т. Д. - Что и делает метод SignUp, он запускает событие домена
NewSubscriberAddedToMusicService
.Это поймано EventHandler HandleNewSubscriberAddedToMusicServiceEvent
, которому IFileService
и IEmailService
ввели в его ctor.Реализация этого обработчика находится на уровне службы приложений, НО событие контролируется доменом и MusicService.SignUp
.Это означает, что домен находится под контролем.Eventhandler создает файл и отправляет электронное письмо.
Вы можете сохранить пользователя с помощью обработчика событий ИЛИ сделать метод MusicService.AddSubscriber(...)
для этого.Оба сделают это через IUserRepository
, но это вопрос вкуса и, возможно, как это отразит реальную область.
Наконец ... Я надеюсь, что вы поняли что-то из вышеперечисленного ... во всяком случае.Самое важное - начать добавлять методы «Глаголы» к сущностям и делать совместную работу.В вашем домене также могут быть объекты, которые не сохраняются, они существуют только для передачи между несколькими объектами домена и могут содержать алгоритмы и т. Д.