DDD - Как реализовать высокопроизводительные репозитории для поиска

У меня есть вопрос относительно DDD и шаблона репозитория.

Скажите, что у меня есть Клиентский репозиторий для Клиентского корня агрегата. Получение и Находит, что методы возвращают полностью заполненный агрегат, который включает объекты как Адрес, и т.д. Вся польза. Но когда пользователь ищет клиента в UI, я просто требую 'сводки' агрегата - просто плоский объект с обобщенной информацией.

Одним путем я мог иметь дело с этим, должен назвать метод находки на репозитории как нормальный, и затем на прикладном уровне, отобразить каждый клиентский агрегат на CustomerSearchResult / CustomerInfo DTO и передать их обратно клиенту.

Но моей проблемой с этим является производительность; каждый Клиентский агрегат может потребовать, чтобы несколько запросов заполнили все ассоциации. Таким образом, если мои критерии поиска соответствовали 50 клиентам, это - настоящий хит на DB для того, чтобы потенциально получить данные, в которых я даже не испытываю необходимость.

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

Таким образом, теперь я думаю, что меня оставляют с двумя опциями:

  1. Добавьте дополнительный метод Находки к CustomerRepository, который возвращает список этих сводных объектов путем выполнения одного эффективного запроса.

  2. Создайте цель, созданную CustomerInfoRepository только для чтения, который просто имеет метод находки, описанный в 1.

Но оба из них чувствуют, что я иду вразрез с принципами DDD. Мои репозитории наследовались универсальной основе: Репозиторий, где T: IAggregateRoot. Они сводный информационный объект не является агрегатами и имеет другой тип к T, поэтому действительно № 1 идет вразрез с дизайном.

Возможно, для № 2 я создал бы абстрактный SearchRepository без ограничения IAggregateRoot?

В моем домене существует много подобных сценариев.

Как Вы реализовали бы этот сценарий?

Спасибо, Dave

Обновление

После чтения ответа Theo я думаю, что пойду с опцией № 2 и создам специализированный SearchRepository в своей инфраструктуре, приспособленной к этим сценариям. Прикладной уровень (сервисы WCF) может затем назвать эти репозитории, которые просто заполняют сводный DTOs непосредственно, а не объекты области значений отображения к DTOs.

**** Обновите 2 ****

Хотя я спросил это более чем год назад, я думал, что просто добавлю, что я с тех пор обнаружил CQRS, который нацелен на решение этой точной проблемы. Udi Dahan (http://www.udidahan.com/) и Greg Young (http://codebetter.com/gregyoung/) записали много об этом. При создании распределенного приложения с DDD CQRS для Вас!

25
задан saggu 4 April 2014 в 12:52
поделиться

2 ответа

Его начало, он может перечислить:

models = Dir.new("#{RAILS_ROOT}/app/models").entries

Глядя еще...

-121--2012847-

При создании собственных потоков (не потоков BackgroundWorker или ThreadPool) можно передать метод обратного вызова из основного потока, вызываемого из рабочего потока. Это также позволяет передавать аргументы в обратный вызов и даже возвращать значение (например, флаг перехода/отказа). При обратном вызове вы обновляете пользовательский интерфейс через диспетчер целевого элемента управления:

public void UpdateUI(object arg)
{
    controlToUpdate.Dispatcher.BeginInvoke(
        System.Windows.Threading.DispatcherPriority.Normal
        , new System.Windows.Threading.DispatcherOperationCallback(delegate
        {
            controToUpdate.property = arg;
            return null;
        }), null);
    }
} 
-121--4213547-

Я думаю, что вы хотите отобразить только сводную информацию. Эти биты обобщенной информации не являются сущностями или ценностными объектами модели домена. Это только информация, не более того.

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

Но имейте в виду, что вы просто создаете информационные значения вне модели для целей отображения. Таким образом, если пользователь выбирает один бит информации для выполнения какой-либо операции с ней (которая определена в модели домена), необходимо извлечь идентификатор из информационных значений и извлечь объект сущности/значения/агрегат из репозитория.

Я настоятельно рекомендую это видео: Эрик Эванс: Что я узнал о DDD со времени книги . Если вы читаете его книгу, вы действительно должны увидеть все видео. Обратите очень пристальное внимание примерно в 30:00, где Эрик Эванс сам говорит об агрегатах и ссылается на проблему, которая у вас в настоящее время есть.

25
ответ дан 28 November 2019 в 21:46
поделиться

Я бы:

  1. вернуть другой объект, который представляет собой вид на мой объект для отображения, например, CustomerInfo.
  2. Верните DataTable. Часто общий контейнер - самый простой и лучший способ пойти.

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

1
ответ дан 28 November 2019 в 21:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: