- Сущность должна быть частной для агрегирования
Да. И я не думаю, что это проблема. Продолжайте читать, чтобы понять, почему.
- Нам нужна копия Value-Object, доступная только для чтения, для предоставления информации от сущности (по крайней мере, для того, чтобы репозиторий мог ее прочитать, чтобы
сохранить в БД, например)
Нет. Сделайте так, чтобы ваши агрегаты возвращали данные, которые должны быть сохранены и / или должны быть получены в событии для каждого метода агрегата.
Сырой пример. Реальному миру потребовался бы более детальный ответ, и, возможно, performMove
функция должна использовать вывод game.performMove
, чтобы построить структуры propper для persistence
и eventPublisher:
public void performMove(String gameId, String playerId, Move move) {
Game game = this.gameRepository.load(gameId); //Game is the AR
List<event> events = game.performMove(playerId, move); //Do something
persistence.apply(events) //events contains ID's of entities so the persistence is able to apply the event and save changes usign the ID's and changed data wich comes in the event too.
this.eventPublisher.publish(events); //notify that something happens to the rest of the system
}
Сделайте то же самое с внутренними сущностями. Позвольте объекту повторно выполнить данные, которые изменились, потому что его вызов метода, включая его ID, захватывает эти данные в AR и формирует пропускающий вывод для постоянства и eventPublisher. Таким образом, вам даже не нужно выставлять открытое свойство readonly для объекта с идентификатором объекта в AR и AR, а также в отношении своих внутренних данных службе приложений. Это способ избавиться от объектов мешков Геттеров / Сеттеров.
- Методы, которые мы имеем на сущности, дублируются на Агрегате (или наоборот, методы, которые мы должны иметь на Агрегате, которые обрабатывают сущность
дублируются на сущность)
Иногда бизнес-правила, для проверки и применения, принадлежат исключительно одному объекту, а его внутреннее состояние и AR просто действуют как шлюз. Это нормально, но если вы найдете этот шаблон слишком много, то это признак неправильного дизайна AR. Может быть, внутренняя сущность должна быть АР, а не внутренней сущностью, может быть, вам нужно разделить АР на несколько АР (и одна из них - старая нерная сущность) и т. Д. Не бойтесь иметь классы, имеющие только или два метода.
В ответ на комментарии ди * зг:
Что точно делает persistance.apply (события)? это спасает весь
только совокупность или субъекты?
Ни. Агрегаты и сущности являются понятиями предметной области, а не понятиями постоянства; у вас может быть хранилище документов, хранилище столбцов, реляционное и т. д., которое не должно совпадать с 1: 1 вашего домена. Вы не читаете Агрегаты и сущности с упорства; Вы строите агрегаты и сущности в памяти с данными, считанными с постоянства. Сама совокупность не нуждается в сохранении, это просто возможная деталь реализации. Помните, что агрегат - это просто конструкция для организации бизнес-правил, а не представление о состоянии.
Ваши события имеют контекст (намерения пользователя) и данные, которые были изменены (вместе с идентификатором, необходимым для идентификации вещей в постоянстве), поэтому невероятно легко написать функцию apply
в слое постоянства, который знает, т.е. какую инструкцию sql в случае реляционной БД, что выполнить, чтобы применить событие и сохранить изменения.
Не могли бы вы привести пример, когда и почему его лучше (или даже
неизбежно?) использовать дочернюю сущность вместо отдельной AR, на которую ссылается
его идентификатор в качестве объекта значения?
Почему вы разрабатываете и моделируете класс с насыщенностью и поведением?
Для абстрагирования, инкапсуляции, повторного использования и т. Д. Базовый SOLID дизайн. Если у сущности есть все необходимое для обеспечения правил и инвариантов домена для операции, тогда эта сущность является AR для этой операции. Если вам нужны дополнительные проверки правил домена, которые не могут быть выполнены объектом (т. Е. У объекта недостаточно внутреннего состояния, чтобы выполнить проверку, или он не вписывается в сущность и то, что представляет), то вам придется перепроектировать; Иногда может потребоваться смоделировать агрегат, который выполняет дополнительные проверки правил домена, и делегировать проверку других правил домена внутренней сущности, иногда можно изменить сущность для включения новых вещей. Это слишком зависит от контекста домена, поэтому я не могу сказать, что существует фиксированная стратегия редизайна.
Имейте в виду, что вы не моделируете агрегаты и сущности в своем коде. Вы моделируете только классы с поведением для проверки правил домена и состояния, необходимого для проверки и ответа с изменениями. Эти классы могут выступать в качестве агрегатов или объектов для различных операций. Эти термины используются только для того, чтобы помочь связать и понять роль класса в контексте каждой операции. Конечно, вы можете оказаться в ситуации, когда операция не вписывается в сущность, и вы можете смоделировать агрегат с помощью V.O. идентификатор персистентности и все в порядке (к сожалению, в DDD, не зная контекста домена, по умолчанию почти все в порядке).
Хочешь больше просветления от кого-то, кто объясняет вещи намного лучше меня? (не быть носителем английского языка - это препятствие для решения этих сложных вопросов) Посмотрите здесь:
https://blog.sapiensworks.com/post/2016/07/14/DDD-Aggregate-Decoded-1
http://blog.sapiensworks.com/post/2016/07/14/DDD-Aggregate-Decoded-2
http://blog.sapiensworks.com/post/2016/07/14/DDD-Aggregate-Decoded-3