3

Я написал приложение и попытался использовать DDD как можно дальше. У меня возникла проблема, и я не уверен, как обращаться. Большая часть системы управляется через пользователей через веб-интерфейс, объем запросов, которые приложение довольно низкое и довольно CRUDy в природе. Однако есть одна часть системы, которая интегрируется в другие онлайн-системы, и объем запросов будет существенным. Мы уже знаем из предыдущего опыта, что мы должны максимально упростить это.Как я могу избежать первого получения корня агрегата для оптимизации в дружественном DDD-режиме?

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

var foo = fooRepo.Get(id); 
if (foo != null) 
{ 
    foo.Bars.Add(new Bar("hello")); 
    fooRepo.Add(foo); 
} 
else 
{ 
    var foo = new Foo(); 
    foo.Bars.Add(new Bar("hello")); 
    fooRepo.Add(fooo); 
} 

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

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

Очевидно, что хранилища не работают в моем сценарии, потому что я не могу рассматривать проблему, как в коллекции элементов памяти. (На самом деле есть всего лишь способ получить много данных, чтобы даже кэшировать все). Лучшая вещь для производительности - это прямая запись в БД.

Есть ли что-нибудь, что можно сделать в этом сценарии? Или я должен просто кодировать исключение?

+0

Хорошо, вы уверены, что вам нужна коллекция 'Bars' на агрегате' foo'? Что вы защищаете от этого? – plalx

ответ

1

Вы могли бы иметь FooRepository.AddOrUpdate(foo, bar) метод, реализованный в виде прямого заявления INSERT INTO ... IF NOT EXISTS или MERGE INTO SQL, если дополнительный туда-обратно действительно беспокойство (который я не совсем уверен, почему это было бы).

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

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

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

Смежные вопросы