Я пытаюсь понять лучшие практики для отношений между сущностями и агрегатами.
Представьте себе проект, в котором у вас есть Совокупный продукт, состоящий из двух сущностей:
Совокупный корень: продукт
Дочерняя сущность: Sku
Где у продукта может быть много Skus. Номера деталей и названия Skus и Product неизменны, поскольку изменение названия одного должно транзакционно обеспечить обновление другого. Точно так же агрегат продукта должен гарантировать, что никогда не будет дублироваться Skus.
У нас есть еще один Агрегат: StorageLocation. где хранится 1 или более Skus. Однако важно, чтобы StorageLocation знал конкретный Sku, который он хранит. т.е. В StorageLocation в Канаде должны храниться Sku, локальные для этой страны, а не Sku, предназначенные для рынка США.
Для меня это означает, что StorageLocation должен хранить ссылку на Sku (поскольку ссылка на агрегированный корень продукта сама по себе не предоставляет достаточно информации для определения сохраняемой Sku).
Судя по моим прочтениям, это, похоже, нарушает принцип, согласно которому другой агрегат не должен содержать ссылку на некорневой объект в другом агрегате. Итак, вопрос:
Спасибо





Рекомендация не хранить ссылку на дочернюю сущность основывается на хороших принципах, но я считаю, что часто вызывает путаницу. На самом деле цель состоит в том, чтобы дочерняя сущность не обязательно имела «глобально уникальный» идентификатор и чтобы ни один репозиторий не предоставлял прямой доступ к дочерней сущности с использованием такого глобально уникального идентификатора.
Однако, если ваш StorageLocation содержит глобальный уникальный идентификатор для Product, а также, возможно, локальный уникальный идентификатор для SKU, тогда нет ничего плохого в таких шаблонах, как:
var storageLocation = _storageLocationRepository.Get(id);
var product = _productRepository.Get(storageLocation.ProductId);
product.DoSomethingToSku(storageLocation.SkuId);
Ключ в том, что, гарантируя, что вы всегда получаете продукт из репозитория, а затем взаимодействуете с дочерней сущностью через продукта, вы гарантируете, что продукт имеет возможность защитить свои собственные инварианты.
Итак, подведем итог:
Is holding just an identifier to the Product and Sku in the StorageLocation aggregate acceptable?
Да, поскольку идентификаторы являются объектами значений в DDD, сохранение идентификатора в агрегате StorageLocation не нарушает правила хранения ссылки на дочерний объект другого агрегата, поскольку объект значения является просто объектом значения и больше не имеет прямой связи с исходным совокупный.
I'm aware that a transient reference is deemed allowable, but in this instance (at least as far as I can tell) this information needs to be stored. As mentioned, storing a reference to the Product (or ProductId) is not enough.
Обезвоживание корня агрегата StorageLocation обратно в базу данных должно включать все, что необходимо сохранить. Уровень инфраструктуры определяет, как ваши объекты домена хранятся в физическом репозитории, и может представлять собой совершенно иной дизайн модели, чем ваша модель предметной области, в зависимости от проблем, связанных с технологией сохранения.
Product and Skus have natural identifiers (Part Number, Sku Number). Does this provide greater flexibility for storing these values in the StorageLocation aggregate as they have meaning beyond technical implications.
Нет ничего, с чем можно было бы сравнивать «большую гибкость», потому что вы будете использовать только естественные идентификаторы или временные ссылки для ссылки на сущности внутри агрегата Product из агрегата StorageLocation.
Am I approaching this the wrong way and need to look at things differently. I often find it difficult to break out of a PK / FK mindset.
Имейте в виду, что проблемы уровня сохраняемости не должны связываться с моделью предметной области и что цель состоит в том, чтобы сделать модель предметной области ясной и синонимичной текущим бизнес-правилам.
«Руководство не хранить ссылку на дочернюю сущность основано на хороших принципах, но я считаю, что часто вызывает путаницу». Да, согласен. В вашем резюме есть два хороших руководящих принципа. Спасибо.