Вероятно, подобные вопросы задавались много раз, но я думаю, что каждый ответ помогает лучше понять и понять DDD. Я хотел бы описать, как я воспринимаю некоторые аспекты DDD. У меня есть некоторые основные неопределенности вокруг него, и я был бы признателен, если бы кто-то мог дать солидный и практичный ответ. Обратите внимание, что эти вопросы предполагают "классический" подход к DDD. Это означает использование ORM и т.д. Подходы, такие как CQRS и источники событий, здесь не рассматриваются.
-
Агрегаты и сущности являются первичными объектами, реализующими логику домена. У них есть состояние и идентичность. В этом контексте я воспринимаю логику домена как совокупность всех команд, которые мутируют это состояние. Имеет ли это смысл? Почему логика домена связана исключительно с государством? Является ли законным моделировать объекты домена, которые не имеют идентификатора или не имеют состояния? Почему объект домена не может быть реализован как транзакция script? Пример. Рассмотрим объект, который рекомендует вам партнера для сайта знакомств. У этого объекта нет реального состояния, но в нем довольно много логики домена? Помещение этого в сервисный уровень подразумевает, что модель домена не может охватить всю логику.
-
Доступ к другим объектам домена. Может ли агрегат иметь доступ к репозиторию? Пример. Когда объект (stateful) домена должен иметь доступ ко всем "пользователям" системы для выполнения своей работы, ему потребуется доступ к ним через репозиторий. Как следствие, ORM нужно будет вводить репозиторий при загрузке объекта (что может быть технически более сложным). Если объекты не могут иметь доступ к репозиториям, где бы вы поместили логику домена для этого примера? В служебном слое? Разве не должен быть логический уровень сервиса?
-
Агрегаты и сущности не должны разговаривать с внешним миром, их беспокоит только ограниченный контекст. Мы не должны вводить внешние объекты (например, IPaymentGateway или IEmailService) в объект домена, это приведет к тому, что домен обрабатывает исключения, поступающие извне. Решение: основанный на событиях подход. Как вы отправляете события? Вам все равно нужно вводить правильные "слушатели" каждый раз, когда вы создаете объект домена. ORM - это восстановление "данных", но они не предназначены для инъекций. Нужна ли нам комбинация DI-ORM?
-
Объекты домена и DTO. Когда вы запрашиваете корень агрегата для своего состояния, он возвращает проекцию своего состояния (DTO) или самих объектов домена? В большинстве моделей, которые я вижу, клиенты имеют полный доступ к модели данных домена, внося глубокую связь с фактической структурой домена. Я воспринимаю "граф объектов" за совокупностью как свой собственный бизнес. Это инкапсуляция, не так ли? Поэтому для меня совокупный корень должен возвращать только DTO. DTO часто определяются на уровне сервиса, но мой подход заключается в моделировании его в самом домене. Уровень обслуживания может все же добавить еще один уровень абстракции, но это другой выбор. Это хороший совет?
-
Репозитории обрабатывают все операции CRUD на уровне совокупного корня. Как насчет других запросов? Запросы возвращают объекты DTO, а не объекты домена. Чтобы это сработало, репсор должен знать структуру данных домена, которая вводит связь. Мой совет аналогичен предыдущему: используйте события для заполнения представлений. Таким образом, внутренняя структура не становится общедоступной, только события содержат необходимые данные для создания представления.
-
Единица работы. Контроллер на границе системы будет создавать команды и передавать их на сервисный уровень, который, в свою очередь, загружает соответствующие агрегаты и пересылает команды. Контроллер может использовать несколько команд и передавать их нескольким службам. Все это контролируется единицей работы. Это означает, что репозитории, сущности, службы - все участвуют в одной транзакции. Вы согласны?
-
Логика Buisness не является логикой домена. С точки зрения бизнес-реализации реализация прецедента может включать в себя множество шагов: Регистрация клиента, отправка электронной почты, создание учетной записи хранилища и т.д. Этот общий процесс может оказаться несовместимым с корнем домена. Объект домена должен иметь доступ ко всей инфраструктуре. Решение: рабочие процессы или саги (или транзакция script). Это хороший совет?
Спасибо