Лучшие практики для работы со ссылками в совокупных корнях и сущностях

Допустим, у меня есть

  • Совокупный корень A, который имеет сущность B

  • Совокупный корень C, который имеет сущность D

Я читал, что лучше всего хранить идентификатор объекта внутри агрегатных корней вместо прямых ссылок, например, A->C_Id и C->A_Id.

  • Может ли агрегат содержать идентификатор объекта в отдельном агрегате? Как A->D_Id и C->B_Id?
  • один агрегатный корень может создать экземпляр другого агрегатного корня? Как например, экземпляр C и наоборот?
  • Может ли агрегат создавать новые экземпляры сущностей, хранящихся в отдельных агрегатах? Как A пытается создать экземпляр D или C пытается создать экземпляр B?
  • Могут ли агрегаты и / или методы сущностей принимать в качестве аргументов прямые ссылки на сущности из других агрегатов, при условии, что они не будут хранить прямые ссылки после выхода из метода? Как A->method(D) или B->method(C)

3 ответа

Я читал, что лучше всего хранить идентификатор объекта внутри агрегатных корней вместо прямых ссылок, например, A->C_Id и C->A_Id.

Да, это рекомендуемый способ.

Может ли агрегат содержать идентификатор объекта в отдельном агрегате? Как A->D_Id и C->B_Id?

Да, но только для того, чтобы использовать эту информацию на стороне чтения (т.е. в пользовательском интерфейсе), а не использовать ее для защиты инвариантов.

один агрегатный корень может создать экземпляр другого агрегатного корня? Как например, экземпляр C и наоборот?

Я не рекомендую это. заполнитель A будет много ответственности. Также агрегаты должны быть независимы друг от друга.

Может ли агрегат создавать новые экземпляры сущностей, хранящихся в отдельных агрегатах? Как A пытается создать экземпляр D или C пытается создать экземпляр B?

Ни при каких условиях. Это нарушит инкапсуляцию другого Агрегата.

Могут ли агрегаты и / или методы сущностей принимать в качестве аргументов прямые ссылки на сущности из других агрегатов, при условии, что они не будут хранить прямые ссылки после выхода из метода? Как A->method(D) или B->method(C)

Я не рекомендую это, поскольку это соединит много двух Агрегатов. Вместо этого вы должны передать примитивы или объекты Value.

Да:)

Нет никакой реальной причины, почему любой из ваших вариантов был бы неправильным.

Может ли агрегат содержать идентификатор объекта в отдельном агрегате? Как A->D_Id и C->B_Id?

Если есть реальные отношения, то это, безусловно, возможно.

один агрегатный корень может создать экземпляр другого агрегатного корня? Как например, экземпляр C и наоборот?

Наличие одного агрегата в качестве фабрики для другого абсолютно нормально. Обычно это требует, чтобы оба были в одном и том же ограниченном контексте.

Может ли агрегат создавать новые экземпляры сущностей, хранящихся в отдельных агрегатах? Как A пытается создать экземпляр D или C пытается создать экземпляр B?

То же, что и выше.

Могут ли агрегаты и / или методы сущностей принимать в качестве аргументов прямые ссылки на сущности из других агрегатов, при условии, что они не будут хранить прямые ссылки после выхода из метода? Как A->method(D) или B->method(C)

Это совершенно разумно, но, опять же, это возможно только тогда, когда сущности находятся в одном и том же ограниченном контексте. При этом вполне возможно использовать объект значения, представляющий совокупность из другого BC в качестве этого экземпляра.

Может ли агрегат содержать идентификатор объекта в отдельном агрегате? Как A->D_Id и C->B_Id?

Вы имеете в виду некорневую сущность? Просто ID, как правило, не поможет, так как не-AR сущности не могут быть напрямую получены через репозитории. Вам нужно будет хранить как идентификатор объекта, так и его родительский Aggregate Root ID. Запоминание слишком многих вещей внутри другого агрегата также может быть запахом кода.

один агрегатный корень может создать экземпляр другого агрегатного корня? Как например, экземпляр C и наоборот?

Конечно. В некоторых подходах это даже рекомендуемый способ создания AR.

Может ли агрегат создавать новые экземпляры сущностей, хранящихся в отдельных агрегатах? Как A пытается создать экземпляр D или C пытается создать экземпляр B?

Почему бы и нет, хотя я не могу придумать правильный пример сейчас, кроме, может быть, с простыми объектами значения. Ты имеешь в виду?

Могут ли агрегаты и / или методы сущностей принимать в качестве аргументов прямые ссылки на сущности из других агрегатов, при условии, что они не будут хранить прямые ссылки после выхода из метода? Как A->method(D) или B->method(C)

Да, временные ссылки в порядке.

Другие вопросы по тегам