假设我有一个实现以下业务规则/策略的域服务:
如果“家庭”类所有产品的总价超过100万,则对超过一年的家庭产品降价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
(请注意,在域服务中再次过滤产品(内存中)也无济于事,因为调用者可能只传递了所有产品的一个子集。 - 应用层不知道哪些产品发生了变化,因此被迫全部保存,这可能是很多多余的工作。
问:有没有更好的策略来处理这种情况?
我想到了一些复杂的事情,例如调整基于持久性的存储库,使其在域服务中显示为基于集合的存储库,在内部跟踪由域服务加载的产品,以便在域服务时再次保存它们返回。