Как смоделировать порядок сортировки «многие к одному» по двум сводным корням

Возьмем домен, предложенный в разделе Эффективный совокупный дизайн продукта, который имеет несколько выпусков. В этой статье Вон приходит к выводу, что и Продукт, и Релиз должны быть собственными сводными корнями.

Теперь предположим, что мы добавляем функцию

  • Как менеджер релизов я хотел бы иметь возможность сортировать релизы, чтобы составлять сроки для выпуска больших эпиков для наших пользователей

Я не продакт-менеджер с особыми потребностями, но кажется разумным, что они хотели бы иметь возможность сортировать выпуски в пользовательском интерфейсе.

Я не совсем уверен, как это должно работать. Для каждого Релиза естественно иметь свойство заказа, но изменение порядка потребует изменения нескольких агрегатов в одной и той же транзакции. С другой стороны, если эта информация хранится в агрегате Product, у вас должен быть такой метод, как product.setRelaseOrder(ReleaseId[]), который кажется странным битом данных для хранения в совершенно другом месте, чем Releases. Хуже того, добавление релиза снова повлечет за собой модификацию двух разных агрегатов! Что еще мы можем сделать? ProductReleaseSortOrder может быть отдельным агрегатом, но это звучит просто абсурдно!

Так что делать? На данный момент я все еще склоняюсь к варианту «позволить продукту управлять им», но что здесь правильно?


person George Mauer    schedule 28.07.2014    source источник


Ответы (2)


Таким образом, Продукт и Релиз являются AR. Выпуск связан с продуктом через AggregateId. Вы хотите получить список всех релизов для данного продукта, заказанного чем-то?

Так как порядок является атрибутом агрегата, то он должен быть установлен для Продукта, но Релизы также являются AR, и вы не должны обращаться к репозиторию Релиза в AR Продукта (каждый AR должен иметь свой собственный репозиторий).

Я бы просто создал ReleaseQueryService, который принимает productId и параметр заказа и вызывает ReleaseRepository.loadOrderedReleasesForProduct(productId, order).

Я бы также подумал о разделении контекстов, может быть, модель для презентации релиза должна быть в другом контексте? В примере дополнительные AR ProductReleases, которые будут использоваться только для запросов.

person Rafał Łużyński    schedule 12.08.2014
comment
Используя эту стратегию, казалось бы, что-то вроде этого создаст лучший вездесущий язык releases.loadOrderedForProduct(product). У меня было предположение, что, возможно, это означает, что OrderedProductReleases может быть другим AR - person George Mauer; 12.08.2014
comment
Я избегаю использования репозиториев внутри AR, потому что AR не несет ответственности за сохранение данных (это нарушает принцип единой ответственности SRP от SOLID), а также затрудняет модульное тестирование логики домена AR. Так что releases.loadOrderedForProduct(product) будет неправильным imo. Попробуйте использовать другой AR OrderedProductReleases и создайте другой репозиторий для этого AR. - person Rafał Łużyński; 12.08.2014
comment
Я думаю, вы меня неправильно поняли (моя вина, так как я изменил ваше соглашение). releases — это экземпляр ReleasesRepository, я просто называю переменную экземпляра releases, поскольку репозиторий представляет собой набор сущностей. - person George Mauer; 12.08.2014
comment
ну тогда должно быть нормально - person Rafał Łużyński; 12.08.2014

Я обнаружил, что на самом деле лучше всего создать новый общий корень (например, ProductReleaseSorting, как предлагается) для каждой отдельной сортировки и/или упорядочения. Это связано с тем, что releaseOrder явно не является свойством Product, то есть чем-то, что само по себе имеет значение для продукта. Скорее, это свойство "представления" для коллекции продуктов, и это представление должно быть смоделировано отдельно.

Причина, по которой я стараюсь вводить новый совокупный корень для каждого отдельного представления набора элементов, становится ясной, если вы думаете о том, что произойдет, если вы в будущем введете дополнительные заказы, скажем, «маркетинговый заказ» или несколько менеджеров по продуктам. хотят сохранить свой собственный порядок и т. д. Здесь легко увидеть, что «маркетинговый заказ» и «заказ на выпуск» — это два разных понятия, которые следует рассматривать независимо, и если несколько человек хотят заказать продукты с одним и тем же ключом, но используя разные заказы, вам понадобятся индивидуальные «просмотры на человека». Кроме того, может случиться так, что существует несколько критериев порядка, которые хотелось бы учитывать при сортировке (примером последнего может быть (в другом контексте) самый быстрый маршрут против кратчайшего маршрута), все из которых зависят от представления. у вас на коллекцию, а не на отдельные свойства ее элементов.

Если теперь вы обрабатываете сортировку менеджера по продукту в совокупности ProductReleaseSorting, вы

  1. иметь единый источник достоверной информации для заказа (AR),
  2. ProductReleaseSorting AR может ввести такие ограничения, как отсутствие двух продуктов с одинаковым номером заказа, и вы
  3. не сталкивайтесь с проблемой обновления нескольких AR в одной транзакции при изменении порядка.

Обратите внимание, что ваш агрегат ProductReleaseSorting, скорее всего, имеет уникальный идентификатор ("Singleton") в вашем домене, т. е. все менеджеры продуктов имеют одинаковую сортировку. Однако, если все члены команды хотели бы иметь свой собственный ProductReleaseSorting, это можно легко поддержать, присвоив ProductReleaseSorting соответствующий идентификатор. Точно так же более общий ProductSorting можно получить по идентификатору для каждой команды (маркетинг или управление продуктами) из репозитория. Все это легко сделать с новым отдельным сводным корнем для упорядочивания, но сложно, если вы добавите свойства к базовым элементам/сущностям.

person Alexander Langer    schedule 15.08.2014
comment
Спасибо за ответ, это не то, что я сделал в моем случае, поскольку мои потребности были более согласованы с другим ответом, но это определенно совершенно законный вариант. Одна вещь, однако, я, вероятно, не стал бы использовать этот подход, если бы порядок сортировки был только заботой о представлении, пока поддержка нескольких пользователей не была действительно необходима. Однако, если бы порядок сортировки влиял на бизнес-логику, я бы сделал его собственной дополненной реальностью. - person George Mauer; 17.08.2014
comment
@GeorgeMauer С тех пор вы стали лучше понимать эту проблему? Я борюсь с аналогичной проблемой, когда у меня есть AR пользователя и AR страны, и мне нужно сортировать пользователей по имени их страны. В настоящее время я склоняюсь к моделированию его как отдельного сервиса. - person Shade; 02.10.2019