Вопрос о DDD, 5-уровневой модели и бизнес-логике
Насколько я понимаю, модель в DDD разделена на следующие уровни:
- Хранение (база данных, файл, кеш...)
- Картограф (берет данные из хранилища)
- Репозиторий (управляет данными для одного типа сущности, может использовать разные сопоставители)
- Entity (простой контейнер данных, независимый от других уровней)
- Сервис (обрабатывает бизнес-логику, например, получает 5 новейших постов в алфавитном порядке по заголовкам, использует репозиторий)
Итак, это 5 ярусов (поправьте меня, если я что-то не так понял). И вопрос такой:
Если у меня есть бизнес-логика, связанная с одной сущностью, я должен реализовать ее в сущности или в службе?
Например, если у меня есть сообщение, и я хочу получить все одобренные комментарии, должно ли это быть Post.getApprovedComments
(сущность) или CommentsService.getApprovedCommentsForPost(Post post)
?
(Нет, это не правильно использовать post.getComments().filter(comment -> comment.approved)
потому что это выводит бизнес-логику из модели. На всякий случай, если кто-то спросит.)
1 ответ
Итак, это 5 ярусов (поправьте меня, если я что-то не так понял).
Я думаю, что люди часто группируют хранилище данных, ORM и репозиторий в один "слой", что касается вашего кода. Также не забывайте о презентации.
Если у меня есть бизнес-логика, связанная с одной сущностью, я должен реализовать ее в сущности или в службе?
Да, если это поведение, связанное с сущностью, тогда оно должно находиться внутри сущности. Сущности не должны быть простыми контейнерами данных, скорее слой Entity/Model должен инкапсулировать как структуру данных, так и поведение, связанное с вашей бизнес-моделью. Таким образом, если вам нужно повторно использовать слой Model в другом приложении, вам не нужно копаться, чтобы найти связанное поведение, которое вы застряли в других слоях.
Например, если у меня есть сообщение и я хочу получить все одобренные комментарии, > должно ли это быть Post.getApprovedComments (entity) или> CommentsService.getApprovedCommentsForPost(Post post)?
Трудно сказать, не зная больше о вашей архитектуре и ORM. Я бы, вероятно, пошел с маршрутом Post.. (комментарии должны быть собранием сущности Post), а затем getApprovedComments мог бы быть простым запросом linq или чем-то подобным. Подход, основанный на услугах, который вы предлагаете, не выглядит для меня ООП
(Нет, неправильно использовать post.getComments(). Filter(c -> comment.approved), потому что это выводит бизнес-логику из модели. На всякий случай, если кто-то спросит.)
Я не совсем уверен, что согласен с вами здесь. Для чего-то такого простого, некоторые могут посчитать это приемлемым.
Я бы добавил, что:
Сервис (обрабатывает бизнес-логику, например, получает 5 новейших постов в алфавитном порядке по заголовкам, использует репозиторий)
... на мой взгляд, это не хороший пример услуги. Уровень сервиса в этом примере ничего не делает - это должен быть просто метод запроса, определенный в PostRepository.
Надеюсь, что это поможет немного...