DDD-как я могу избежать пересечения границ агрегата здесь?


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

Вот (упрощенная) версия двух ключевых частей в нашей модели предметной области:

текст Alt

Как вы можете видеть, у меня есть абстрактная концепция поста , который может быть обзором, обсуждением, фотографией, видео и т. д. Сообщения также могут иметь комментарии.

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

Теперь это, естественно, выглядело для меня как два ясных агрегатных корня. Поэтому я создал два репозитория, один из которых называетсяPostRepository , а другой - LocationRepository .

Все это прекрасно работало, я могу добавить/получить любой тип сообщения (или комментария) и добавить/получить любой тип местоположения через один из этих двух репозиториев.

Но теперь я в сценарии "посадочной страницы" для города (для образец).

На этой странице мне нужно в основном показать "все сообщения для этого местоположения".

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

Но как я могу получить эту информацию, не пересекая границ?

Какой репозиторий я использую? Нужен ли мне новый?

Если это имеет значение (или для любопытных), это веб-приложение (ASP.NET MVC), с базой данных SQL Server 2008 и Entity Framework 4.0.

Если вам нужны какие-либо разъяснения, дайте мне знать.

EDIT

В настоящее время мы используем модифицированную версию шаблона спецификации для получения моделей предметной области.

Например, это код в нашем BLL, чтобы получить все отзывы, где оценка >= 4:

var reviews = postRepository // GenericRepository<Post>
      .Find() // IQueryable<Post>
      .OfType<Review>() // IQueryable<Review>
      .Where(x => x.Score >= 4)
      .ToList(); // List<Review>

Но теперь мне нужен такой код:

var reviews = postRepository
    .Find()
    .OfType<Review>()
    .Where( //lat long, or Locations FK )
    .ToList();

Проблема в том, что я не знаю, как выполнить вышеприведенный запрос без добавления промежуточной сущности join (LocationPost-поскольку это много ко многим) и добавить FK к модели домена Post.

Но делая это, я пересекаю границы совокупности-не так ли?
3 5

3 ответа:

Я бы привязал запись к местоположению во время создания, чтобы для каждого местоположения я мог получить (через репозиторий) список связанных записей. Это выглядело бы так:

Создание:

var p = new Post(latitude, longitude);
var locations = locationRepository.FindByCoordinates(latitude, longitude);
foreach (var l in locations)
{
    l.AssociatePost(p);
}
session.Save(p);

Извлечение:

var associatedPosts = postRepository.FindByLocation(locationId);
foreach (var p in associatedPosts)
{
    Display(p);
}

Под капотом связь между должностями и местоположением будет реализована в виде отношения таблицы "многие ко многим". Существует одна проблема с этим решением: добавление нового местоположения требует сканирования всех записей и назначения их новому местоположению (если применимый).

Надеюсь, что помогает.

Почему это проблема? Согласно Эвансу в его книге, один AR может очень хорошо ссылаться на другой AR. (Однако вы не можете ссылаться на дочерний элемент в AR из другого AR)

Кроме того, действительно ли местоположения являются агрегатными корнями? Определение агрегатного корня состоит в том, что он действует как граница консистенции. Соответствует ли это определению местоположения? Я бы сказал, что местоположение-это ценный объект.

Здесь есть в значительной степени два лагеря относительно репозиториев и AR ассоциации:

Тот, который говорит, что все агрегатные корни должны быть извлечены через их соответствующий репозиторий, и AR должны использовать мягкие отношения, например ID между ними

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

Предположим, вы использовали шаблон спецификации, могли бы вы построить спецификацию Post, используя объект Location? Затем вы просто передаете спецификацию в свой почтовый репозиторий и получаете результат.