DDD Java with Spring - 返回 Mono/Flux 的存储库



我想知道在使用Java和Spring Boot实现的DDD项目中实现反应式Mongo存储库时遇到的一个问题。假设我们有这样的包结构:

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

我我的订单存储库.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' 方法返回一个包装的订单 单。这种方法将使用反应器填充域层 特定类型并打破规则说域层应该是 框架代码免费。
  2. 开发某种包装层,但这会产生一些 样板代码。
  3. 将 OrderService.java 移动到基础结构层,但这也破坏了一些基本的 DDD 概念。

有人看到更好的解决方案吗?

存储库应该与框架代码无关,这是真的,这是一个很好的做法,但你也需要务实,我有存储库,我使用了java lambda,这是可以争论的语言级框架。

使用Flux或Mono有什么好处,将它们作为界面的一部分进行宣传有什么好处?如果没有,则可以将实现详细信息保留到存储库实现中,并使接口没有反应式对象。

但是,如果这需要跨越应用程序层到端口适配器,那么我认为将它们放在存储库的接口定义中没有任何问题。

话虽如此,您可能需要检查另一种方法,使用 CQRS 和六边形体系结构,您可以两全其美:

  • 具有命令的干净存储库界面(更新和创建部分)
  • 使用查询服务(如果您在 java 中,则为纯 POJO,在您的应用程序包中定义)为查询返回单声道或通量(读取部分)

    OrderApplicationService.java(这里是创建更新删除命令) OrderQueryService.java(这里是读取部分)

您的应用程序服务包含对 OrderRepository 的引用,查询服务不使用存储库,因为它更直接地查询数据库,例如通过 ReactiveMongoTemplate。

在我的查询服务中,我使用了普通的JDBC模板,例如在存储库实现中使用Hibernate。