Другой совокупный корень для вставки и удаления - PullRequest
0 голосов
/ 25 июня 2019

Представьте, что у нас есть следующее aggregate root:

public class Resource
{
   public IEnumerable<Schedule> schedules {get;private set;}
   ...
}

Когда мы хотим добавить новый schedule, мы должны убедиться, что он не столкнется с существующим. Это означает наличие aggregate root, обеспечивающего этот инвариант в методе resource.AddSchedule(schedule).

С другой стороны, удаление schedule не имеет инвариантов. Если мы используем Resource aggregate root для удаления schedule, нам нужно предварительно загрузить все schedules, чтобы удалить только один.

Исходя из этого, мы должны повысить Schedule до aggregate root, загрузить только тот schedule, который нам нужен, а затем удалить его? Или мы должны продолжать использовать предыдущий aggregate root?

Ответы [ 3 ]

1 голос
/ 26 июня 2019

Когда мы хотим добавить новое расписание, мы должны убедиться, что оно не будет конфликтовать с существующим.

Общий термин для того, чего вы пытаетесь достичь здесь: проверка набора .

Если вам нужна абсолютная уверенность в том, что в наборе нет конфликтующих записей, иногда называемых «немедленной согласованностью», то вы должны быть уверены, что записи не изменяются одновременно с вашей проверкой. Это означает, что значения, которые вас интересуют в вашем чеке , должны быть частью совокупности их проверки - нам нужно, чтобы убедиться, что ответы под нами не меняются.

Более распространенным случаем является то, что «наилучшее усилие» достаточно хорошо, и есть доступные протоколы для разрешения конфликтов, которые проскальзывают через трещины. В этом случае вы часто можете рассматривать набор как список идентификаторов, а не как список значений. Таким образом, подробности можно использовать в агрегате Schedule, а агрегат Resource отслеживает только членство в расписании.

Есть еще один угловой случай - если Расписания являются значениями, а не сущностями ... это означает, что детали для данного расписания являются неизменными, тогда вы можете иметь свой торт и съесть его тоже - вычислить уникальный хеш для каждого запланируйте и сохраните значения хеш-функции в ресурсе, который впоследствии можно будет использовать для поиска неизменного расписания при необходимости.

Большая часть работы здесь заключается в правильном изложении бизнес-требований. В большинстве зрелых бизнес-доменов конфликты случаются достаточно часто, поэтому существуют протоколы для их разрешения. Другими словами, условий гонки не существует .

Разница во времени в микросекундах не должна влиять на основные бизнес-процессы.

0 голосов
/ 26 июня 2019

Исходя из этого, мы должны продвинуть Расписание в совокупный корень

Если Schedule имеет собственный жизненный цикл, то в любом случае он должен быть агрегатом, и это немного изменит ваш дизайн.

Однако, если предположить, что ваши отношения между Resource -> Schedule такие же, как Order -> OrderItem, тогда вы всегда можете сделать так, чтобы хранилище предоставило более простое удаление для Schedule:

public interface IResourceRepository
{
   void Add(Resource resource);
   void RemoveSchedule(Resource resource, Resource.Schedule schedule); // or some such
}

Для Order это, вероятно, не работа, учитывая, что будет , вероятно, будут соответствующими инвариантами.

обновление

Если ваш Schedule является агрегированным корнем, то вы, вероятно, создадите его независимо от Resource и ранее. Уникальность Schedule будет находиться в пределах компетенции проверки набора , как упомянуто @VoiceOfUnreason. Тогда вашему Resource все равно потребуется список ссылок на экземпляры Schedule, но эти ссылки будут либо только Id, либо некоторый объект значения будет содержать Id и любые другие соответствующие биты. Гарантия того, что у вас нет повторяющихся расписаний, будет инвариантом, принудительно установленным Resource.

Чтобы удалить расписание из ресурса, вы вернетесь к первым вариантам: либо загрузите Resource и удалите соответствующее расписание Id, либо просто удалите его "напрямую через репозиторий.

Всегда существует проблема удаления жесткого диска и мягкого, и обычно нужно только изменить статус (мягкое удаление), так как проблем меньше. В таком случае принудительное удаление Schedule, вероятно, будет либо остановлено DRI в хранилище данных (если настроено), либо будет каскадно удалено в соответствующие таблицы.

0 голосов
/ 25 июня 2019

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

  • Приложение работает слишком медленно, когда мы пытаемся удалить расписание
  • Мы хотели бы применить правило X при удалении расписаний

Лично я бы избежал преждевременных оптимизаций, которые в будущем могут загнать вас в угол.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...