简体   繁体   English

如何将存储库与DDD和Spring集成

[英]How to integrate Repository with DDD and Spring

I want to create an app following the DDD approach using Spring. 我想使用Spring按照DDD方法创建一个应用程序。 Supose that I have a business model class Foo and an interface FooRepository . 假设我有一个业务模型类Foo和一个接口FooRepository

DDD tells that the implementation of FooRepository should include in Infrastructure layer. DDD告知FooRepository的实现应包括在Infrastructure层中。

I would want to use CrudRepository but if I define in the domain layer: 我想使用CrudRepository但是如果我在域层中定义:

public interface FooRepository extends CrudRepository<Foo, Long>{
    // Some methods
}

I break with the core concept that the domain layer ( FooRepository interface) must not know the infrastructure layer ( CrudRepository ). 我打破了核心概念,即域层( FooRepository接口)一定不知道基础结构层( CrudRepository )。

I'm reading about this Domain Driven Design a few months ago but I haven't found a framework that supports it purely. 几个月前,我正在阅读有关此域驱动设计的文章,但我还没有找到一个纯粹支持它的框架。

How I can do it the right way? 我怎样才能正确地做到这一点?

In the layered architecture you usually have 3 layers: application , domain and infrastructure . 在分层体系结构中,通常有3层: 应用程序基础架构

Infrastructure 基础设施

Here I put the implementation of the repository. 在这里,我把存储库的实现。 In your case this is the implementation of CrudRepository which I would implement directly in concrete classes, without the use of an intermediate interface. 在您的情况下,这是CrudRepository的实现,我将直接在具体类中实现,而无需使用中间接口。 We make no whatsoever assumption as to how the single object in the warehouse behave, we only put them there and retrieve them efficiently. 我们对仓库中单个对象的行为没有任何假设,我们只将它们放在那里并有效地对其进行检索。 This way we have no knowledge of the domain. 这样,我们就不了解该领域。 We only offer the domain an interface to interact with: the set of public methods of WarehouseRepository. 我们仅为域提供与之交互的接口:WarehouseRepository的公共方法集。

public class WarehouseRepository implements CrudRepository<Foo, Long> {
    ...
}

Domain

Here various part of the model interact with the WarehouseRepository when you are inside a UnitOfWork/Transaction. 当您在UnitOfWork / Transaction中时,模型的各个部分都与WarehouseRepository进行交互。 In the method adjustQuantityPlus we se only domain logic which is not interesting to the application and need not to be known at infrastructure level. 在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
    }
}

Application 应用

Here we start and stop transactions (UOWork) which manipulates many domain objects. 在这里,我们开始和停止处理许多域对象的事务(UOWork)。 Every business method correspond to a business use case. 每个业务方法都对应一个业务用例。

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
    }
}

The above code is a transaction, if the system couldn't add the product to the order I don't want to give the discount to the customer. 上面的代码是一笔交易,如果系统无法将产品添加到订单中,我不想为客户提供折扣。 The adjustQuantityPlus in turn is an inner “transaction” with domain logic, hidden to the application layer. adjustQuantityPlus继而又是带有域逻辑的内部“事务”,隐藏在应用程序层中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM