Предположим, у меня есть служба домена, которая реализует следующее бизнес-правило / политику:
Если общая цена всех продуктов в категории «семейство» превышает 1 миллион, снизьте цену на 50% для семейных продуктов старше одного года.
Использование репозиториев на основе коллекций
Я могу просто создать службу домена, которая загружает все продукты из категории «семейство», используя шаблон спецификации, затем проверять условие и, если оно истинно, снижать цены. Поскольку продукты автоматически отслеживаются репозиторием на основе коллекции, от службы домена вообще не требуется выполнять какие-либо явные вызовы инфраструктуры - как и должно быть.
Использование репозиториев на основе сохраняемости
Мне не повезло. Я мог бы обойтись без использования репозитория и спецификации для загрузки продуктов в мою доменную службу (как и раньше), но в конечном итоге мне нужно сделать Save
вызовы, которые не принадлежат уровню домена.
Я мог бы загрузить продукты на уровне приложения, затем передать их службе домена и, наконец, снова сохранить их на уровне приложения, например:
// Somewhere in the application layer:
public void ApplyProductPriceReductionPolicy()
{
// make sure everything is in one transaction
using (var uow = this.unitOfWorkProvider.Provide())
{
// fetching
var spec = new FamilyProductsSpecification();
var familyProducts = this.productRepository.findBySpecification(spec);
// business logic (domain service call)
this.familyPriceReductionPolicy.Apply(familyProducts);
// persisting
foreach (var familyProduct in familyProducts)
{
this.productRepository.Save(familyProduct);
}
uow.Complete();
}
}
Однако я вижу следующие проблемы с этим кодом:
- Загрузка правильных продуктов теперь является частью уровня приложения, поэтому, если мне нужно снова применить ту же политику в каком-то другом случае использования, мне нужно будет повторить себя.
- Связь между спецификацией (
FamilyProductsSpecification
) и политикой теряется, что позволяет кому-то передавать неправильные продукты в службу домена. Обратите внимание, что повторная фильтрация продуктов (в памяти) в службе домена также не помогает, так как вызывающий мог передать только подмножество всех продуктов. - Уровень приложения не знает, какие продукты были изменены, и поэтому вынужден сохранять их все, что может быть большой избыточной работой.
Вопрос: есть ли лучшая стратегия в этой ситуации?
Я подумал о таком сложном, как адаптация репозитория на основе постоянства, чтобы он отображался как репозиторий на основе коллекции для службы домена, внутренне отслеживая продукты, которые были загружены службой домена, чтобы снова сохранить их, когда служба домена возвращается.