我想知道在使用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接口实现我的方法。
我看到的可能解决方案是:
有人看到更好的解决方案了吗?
答案 0 :(得分:1)
该存储库应该与框架代码无关,这是对的,这是一个好习惯,但是您也需要务实,我有一个使用Java lambda的存储库,这是人们可以争论的语言级别框架。
使用Flux或Mono的好处是什么,将它们作为界面的一部分进行广告有什么好处?如果没有,则可以将实现细节保留在存储库实现中,并使接口没有反应性对象。
但是,如果这需要跨越应用程序层到端口适配器,那么我看不到将它们放入存储库的接口定义中的任何问题。
话虽这么说,您可能想检查另一种方法,借助CQRS和六角结构,您可以兼得两者:
使用查询服务(如果在Java中为纯POJO,在应用程序包中定义),则为查询返回Mono或Flux(阅读部分)
OrderApplicationService.java(通过命令创建更新删除) OrderQueryService.java(在此处为阅读部分)
您的应用程序服务包含对您的OrderRepository的引用,查询服务不使用该存储库,因为它通过例如ReactiveMongoTemplate更直接地查询数据库。
例如,在查询服务中,我在存储库实现中使用Hibernate时使用了普通的JDBC模板。