我想使用Spring在DDD方法之后创建一个应用程序。假设我有一个商业模式类Foo
和一个接口FooRepository
。
DDD告诉FooRepository
的实施应该包含在基础设施层中。
我想使用CrudRepository
,但如果我在域层中定义:
public interface FooRepository extends CrudRepository<Foo, Long>{
// Some methods
}
我打破了核心概念,即域层(FooRepository
接口)必须不知道基础架构层(CrudRepository
)。
我怎么能以正确的方式做到这一点?
答案 0 :(得分:1)
在分层架构中,您通常有3层:应用,域和基础架构。
这里我把存储库的实现。在您的情况下,这是CrudRepository
的实现,我将直接在具体类中实现,而不使用中间接口。我们对仓库中单个对象的行为方式做了 no 无论如何假设,我们只将它们放在那里并有效地检索它们。这样我们就不了解域名。我们只为域提供了一个与之交互的接口:WarehouseRepository的公共方法集。
public class WarehouseRepository implements CrudRepository<Foo, Long> {
...
}
当您在UnitOfWork / Transaction中时,模型的各个部分与WarehouseRepository
交互。在方法adjustQuantityPlus中,我们只选择对应用程序不感兴趣的域逻辑,而不需要在基础结构级别知道。
public class SaleOrder {
public adjustQuantityPlus(LineItemID lineItemID,
WarehouseRepository warehouseRepository) {
this.lineItems.get(lineItemID).addOne(); //<-- add one to the order
Product product =
warehouseRepository.findByLineItem(lineItem);
product.minusOneFromStock(); //<-- decrease one from stock
}
}
这里我们启动和停止操作许多域对象的事务(UOWork)。每种业务方法都对应一个业务用例。
public class CustomerEventsManager {
@Inject WarehouseRepository warehouseRepository;
@Inject SaleOrderRepository saleOrderRepository;
@Transactional
public wantsOneMoreOf(ProductID productID, SaleOrderID saleOrderID) {
SaleOrder saleOrder =
saleOrderRepository.findByID(saleOrderID)
saleOrder.adjustQuantityPlus(productToLineItem(productID),
warehouseRepository); //<-- add product
webPage.showPromoDiscount(); //<-- show promotional advertisement
}
}
上述代码是一项交易,如果系统无法将产品添加到订单中,我不想给客户打折。反过来,adjustQuantityPlus
是一个带有域逻辑的内部“事务”,对应用程序层是隐藏的。