luk*_*och 5 java spring domain-driven-design mongodb project-reactor
我想知道在我使用 Java 和 Spring Boot 实现的 DDD 项目中实现反应式 Mongo 存储库时遇到的一个问题。假设我们有这样的包结构:
/app 
  |
  |------/application
  |        | 
  |        |------/order
  |                 |
  |                 |------OrderApplicationService.java
  |
  |------/domain
  |        |
  |        |------/order
  |                 |
  |                 |------Order.java
  |                 |------OrderRepository.java 
  |
  |------/infrastructure
           |
           |------/mongo
                    |
                    |------MongoOrderRepository.java
Run Code Online (Sandbox Code Playgroud)
我的 OrderRepository.java 我想要一个方法来保存我的订单:
public interface OrderRepository {
    Order save(Order order);
}
Run Code Online (Sandbox Code Playgroud)
并在我的应用程序服务中使用它:
@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());
    }
}
Run Code Online (Sandbox Code Playgroud)
接下来我想编写 MongoOrderRepository 来实现 OrderRepository。假设我将使用 ReactiveMongoTemplate。问题是它的所有方法都返回 Flux 或 Mono,所以我无法从 OrderRepository 接口实现我的方法。
我看到的可能的解决方案是:
有人看到更好的解决方案吗?
存储库应该与框架代码无关,这是事实,这是一种很好的做法,但您也需要务实,我有一个使用 java lambda 的存储库,这是人们可能会争论的语言级框架。
使用 Flux 或 Mono 有什么好处?将它们作为界面的一部分进行广告有什么好处?如果没有,您可以将实现细节保留到存储库实现中,并保持接口没有反应对象。
但是,如果这需要跨越应用程序层到端口适配器,那么我认为将它们放入存储库的接口定义中不会出现任何问题。
话虽这么说,您可能想检查另一种方法,使用 CQRS 和六边形架构,您可以两全其美:
使用查询服务(如果使用 java,则为普通 POJO,在应用程序包中定义)返回 Mono 或 Flux 进行查询(阅读部分)
OrderApplicationService.java(这里是通过命令创建更新删除) OrderQueryService.java(这里是读取部分)
您的应用程序服务包含对 OrderRepository 的引用,查询服务不使用存储库,因为它更直接地查询数据库,例如通过 ReactiveMongoTemplate。
例如,在我的查询服务中,我在存储库实现中使用 Hibernate 时使用了普通 JDBC 模板。