DDD Java with Spring - 仓储返回 Mono/Flux

5

我想请教一个问题,这个问题与在使用Java和Spring Boot实现DDD项目中实现响应式Mongo存储库时遇到的相关。假设我们有以下包结构:

/app 
  |
  |------/application
  |        | 
  |        |------/order
  |                 |
  |                 |------OrderApplicationService.java
  |
  |------/domain
  |        |
  |        |------/order
  |                 |
  |                 |------Order.java
  |                 |------OrderRepository.java 
  |
  |------/infrastructure
           |
           |------/mongo
                    |
                    |------MongoOrderRepository.java

在我的OrderRepository.java文件中,我希望有一个保存订单的方法:

public interface OrderRepository {

    Order save(Order order);
}

并在我的应用程序服务中使用它:

@Service
public class OrderApplicationService {

    private final OrderRepository orderRepository;

    public OrderApplicationService(OrderRepository orderRepository) {
        this.orderRepository = orderRepository;
    }

    public void createOrder() {
        //Dumb order creation
        Order createdOrder = clientRepository.save(new Order());
    }
}

接下来我想编写实现OrderRepository的MongoOrderRepository,假设我将使用ReactiveMongoTemplate。问题是它的所有方法都返回Flux或Mono,所以我无法从OrderRepository接口实现我的方法。
我看到的可能的解决方案有:
  1. 使OrderRepository中的“save”方法返回一个包装在Mono中的Order。这种方法会用Reactor特定类型污染领域层,并打破领域层应该没有框架代码的规则。
  2. 开发某种包装层,但这将产生一些样板代码。
  3. 将OrderService.java移动到基础架构层,但这也违反了一些基本的DDD概念。
是否有更好的解决方案?

2
标准更好的解决方案是使用Spring Data而不编写存储库实现。 - chrylis -cautiouslyoptimistic-
为什么要使用ReactiveMongoTemplate?你可以选择MongoTemplate。问题在于,如果你选择了ReactiveMongoTemplate,那么你的整个项目代码都应该以响应式方式编写,否则使用它就没有意义。 - Rajat Goel
是的,在这个项目中我最终会使用MongoTemplate。我只是想知道一个反应式仓库如何与经典的DDD概念集成,并收集一些关于这方面的观点。谢谢回复。 - lukasz-zimnoch
1个回答

6
代码库应该与框架代码无关,这是正确的做法,但你也需要务实。我曾经使用过Java lambda的仓库,可以说它们是语言级别的框架。
使用Flux或Mono有什么好处,并且将它们作为接口的一部分进行公开有什么好处?如果没有,你可以将实现细节保留在仓库实现中,并使接口不包含响应式对象。
然而,如果需要跨越应用程序层到端口适配器,则我认为将它们放在仓库接口定义中没有任何问题。
话虽如此,你可能想要检查另一种方法,使用CQRS和六边形架构,你可以拥有最佳的两个世界:
- 对于命令(更新和创建部分)具有清晰的仓库接口 - 使用查询服务(如果你在Java中,可以使用普通POJO,在应用程序包中定义)返回一个单独的Flux或Mono来进行查询(读取部分)
你的应用程序服务包含对OrderRepository的引用,查询服务不使用存储库,因为它更直接地查询数据库,例如通过ReactiveMongoTemplate。
在我的查询服务中,我使用了纯JDBC模板,而在存储库实现中则使用了Hibernate。

不确定但是如果全栈不是反应式的,你就得不到一个反应式系统。 - robert trudel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接