DDD - Как я могу избежать пересечения общих границ здесь? - PullRequest
5 голосов
/ 26 ноября 2010

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

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

alt text

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

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

Теперь, естественно, это выглядело как два чистых агрегатных корня.

Итак, я создал два репозитория, один с именем PostRepository , а другой с именем LocationRepository .

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

Но теперь я нахожусь в сценарии «целевой страницы» для города (например,e).

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

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

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

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

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

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

РЕДАКТИРОВАТЬ

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

Например, это код внаш 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();

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

Но тем самым я пересекаю совокупные границы- не так ли?

Ответы [ 3 ]

9 голосов
/ 26 ноября 2010

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

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

Здесь есть два лагеря в отношении хранилищ и ассоциаций AR:

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

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

6 голосов
/ 26 ноября 2010

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

Создание:

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);
}

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

Надеюсь, это поможет.

0 голосов
/ 26 ноября 2010

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

...