Несмотря на то, что мы долгое время изучали Domain Driven Design
, все еще есть некоторые основы, которые я просто выясняю.
Кажется, что каждый раз, когда я пытаюсь создать богатый domain layer
, мне все еще нужно много Domain Services
или толстый Application Layer
, и я получаю кучу сублимированных объектов домена без реальных логики в них, помимо "GetTotalAmount" и тому подобного. Ключевая проблема заключается в том, что сущности не знают о внешнем материале, и плохая практика заключается в том, чтобы вводить что-либо в сущности.
Позвольте привести несколько примеров:
1. Пользователь подписывается на услугу. Пользователь сохраняется в базе данных, файл создается и сохраняется (необходим для учетной записи пользователя), и отправляется сообщение с подтверждением.
Пример с электронным письмом с подтверждением подробно обсуждался в других потоках, но без реального вывода. Некоторые предлагают положить логику в application service
, которая получает EmailService
и FileService
, введенные из infrastructure layer
. Но тогда у меня была бы бизнес-логика вне домена, не так ли? Другие предлагают создать domain service
, который получает infrastructure services
, но в этом случае мне нужно будет иметь интерфейсы infrastructure services
внутри domain layer
(IEmailService
и IFileService
), который не выглядит слишком хорошо (потому что domain layer
не может ссылаться на infrastructure layer
). Другие предлагают реализовать События домена Udi Dahan, а затем подписываются на эти события в службе EmailService и FileService. Но это похоже на очень неудачную реализацию - и что произойдет, если службы потерпят неудачу? Пожалуйста, дайте мне знать, что вы считаете правильным решением здесь.
2. Песня приобретается в магазине цифровой музыки. Корзина покупок опустела. Покупка сохраняется. Вызывается служба оплаты. Подтверждено подтверждение по электронной почте.
Хорошо, это может быть связано с первым примером. Вопрос в том, кто отвечает за организацию этой транзакции? Конечно, я мог бы разместить все в контроллере MVC с помощью инъекционных услуг. Но если я хочу реального DDD, вся бизнес-логика должна быть в домене. Но какой объект должен иметь метод "Покупка"? Song.Purchase()
? Order.Purchase()
? OrderProcessor.Purchase()
(услуга домена)? ShoppingCartService.Purchase()
(служба приложения?)
Это случай, когда мне очень сложно использовать настоящую бизнес-логику внутри объектов домена. Если это не хорошая практика, чтобы что-то вводить в сущности, как они могут делать другие вещи, кроме проверки своего собственного состояния (и его совокупности)?
Я надеюсь, что эти примеры достаточно ясны, чтобы показать проблемы, с которыми я имею дело.