Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 在干净的体系结构中,一个控制器可以调用多个用例(interactor)吗?_Spring_Spring Boot_Architecture_Domain Driven Design_Clean Architecture - Fatal编程技术网

Spring 在干净的体系结构中,一个控制器可以调用多个用例(interactor)吗?

Spring 在干净的体系结构中,一个控制器可以调用多个用例(interactor)吗?,spring,spring-boot,architecture,domain-driven-design,clean-architecture,Spring,Spring Boot,Architecture,Domain Driven Design,Clean Architecture,我正在设计一个带有spring后端的移动应用程序 在我的移动应用程序中,我有一个洗牌按钮。当用户单击按钮时,我从GPS获取用户的当前位置,并随请求发送,然后使用此位置信息查找附近用户到当前用户 顺便说一句,使用相同用例的shuffle和filter用例唯一的区别是当shuffle时,我应用默认的过滤器,如所有年龄、所有距离等 ~~洗牌/筛选请求~~ { interestedGenders: ["WOMAN"] minDistance: 1, maxDi

我正在设计一个带有spring后端的移动应用程序

在我的移动应用程序中,我有一个洗牌按钮。当用户单击按钮时,我从GPS获取用户的当前位置,并随请求发送,然后使用此位置信息查找附近用户到当前用户

顺便说一句,使用相同用例的shuffle和filter用例唯一的区别是当shuffle时,我应用默认的过滤器,如所有年龄、所有距离等

~~洗牌/筛选请求~~

{  
  interestedGenders: ["WOMAN"]  
  minDistance: 1,  
  maxDistance: 100,  
  minAge: 18,  
  maxAge: 65,  
  latitude: 31.4,  
  longitude: 27.1  
}
好的,现在我的问题是我不想实时跟踪/更新用户位置,所以我认为当用户洗牌(或筛选)时,我已经有了用户位置,所以首先我更新数据库中的用户位置,然后我使用此位置信息查找具有其他筛选(性别、年龄等)的附近用户

我在mongo db中有3个简单的集合(帐户、配置文件和用户位置)

~~概要文件(简化)~~

~~用户位置文档~~

{  
  id: "zzz"  
  accountId: "yyy",  
  location: {  type: "Point",  coordinates: [31.4, 27.1]  }  
  lastUpdated: "2020-10-10T00:59:37.154Z"  
} 
这是我使用的代码。首先,我执行更新用户位置用例。更新位置用例如果用户在数据库中没有记录,则创建记录,否则更新用户位置。然后我发现用户符合标准

@ApiController
@AllArgsConstructor
public class FilterProfilesController {

    private final UpdateUserLocationUseCase updateUserLocationUseCase;
    private final FilterProfilesUseCase filterProfilesUseCase;

    @PostMapping("/profiles/filter")
    public ResponseEntity<BaseResponse> filterProfiles(@AuthenticationPrincipal AccountId accountId, @RequestBody FilterProfilesRequest request) {
        var userLocation = new Location(new Latitude(request.getLatitude()), new Longitude(request.getLongitude()));

        updateUserLocationUseCase.execute(new UpdateUserLocationUseCase.Command(accountId, userLocation), () -> {
        });
        
        // Conversions from request to value objects (simplified)
        
        var query = new FilterProfilesUseCase.Query(accountId, userLocation, interestedGenders, ageRange, distanceRange);
        var presenter = new FilterProfilesPresenter();

        filterProfilesUseCase.execute(query, presenter);

        return presenter.getViewModel();
    }
}
@ApiController
@AllArgsConstructor
公共类筛选程序控制器{
私有最终更新UserLocationUseCase更新UserLocationUseCase;
私人最终过滤器使用酶过滤器使用酶;
@后期映射(“/profiles/filter”)
公共响应身份筛选器配置文件(@AuthenticationPrincipal AccountId AccountId,@RequestBody筛选器配置文件请求){
var userLocation=新位置(新纬度(request.getLatitude()),新经度(request.getLongitude());
updateUserLocationUseCase.execute(新的updateUserLocationUseCase.Command(accountId,userLocation),()->{
});
//从请求对象到值对象的转换(简化)
var query=new FilterProfilesUseCase.query(accountId、userLocation、interestedGenders、ageRange、distanceRange);
var presenter=new FilterProfilesPresenter();
filterProfilesUseCase.execute(查询、演示者);
返回presenter.getViewModel();
}
}
设计这个的最佳方式是什么?
如何将更新位置用例(从FilterProfilesController)解耦,但在筛选用例之前仍然调用它?
我应该写一个自定义方面还是什么

对一些问题的回答

Q:为什么我没有将用户位置信息放入内部配置文件集合

A:因为我们在用户注册时不会获得此信息。因此,在用户使用shuffle或filters页面以及我在mongo db中使用地理空间查询之前,位置字段保持为空,因此我猜这可能会导致错误。

Plus profile对象已经有很多字段,我认为分离用户位置为将来的用例提供了很大的灵活性。

通常建议将应用程序的“写”端与“读”端分开

您可能希望独立地扩展查询服务,因为写入与读取不成比例。对于每次写入(GPS位置),您可能需要执行10倍或100倍的查询

在您的示例中,您可能第一次收到GPS位置,但允许用户使用不同的过滤器组合执行多个查询。假设您自动收集用户的GPS位置,则在查询之间可能不会更改

应用程序的域模型通常不适合查询。您通常会构造相同数据的多个表示(写端),以满足不同API(读端)所需的响应格式。您可以通过组合
域事件
订户
来实现这一点,甚至可以单独为查询端创建单独的微服务

因此,最好将
GPS位置更新
用例与查询分开。它会导致两个调用,但您会得到大量的灵活性作为回报


因此,最好让调用者(在本例中是UI)在请求数据之前先执行更新。这还有另外一个好处,即您可以异步收集GPS更新(如ping)以更新用户位置,而不仅仅是在用户请求数据时。

Hey@Subhash感谢您的回答。我像你说的那样分离了api调用。顺便问一下,我可以得到你对自定义读取模型的意见吗?例如,有时我们需要使用2-3个不同的聚合来准备查询结果。你如何处理这种情况。因为存储库必须返回聚合,但例如,如果我想获得具有距离的配置文件,我需要使用2个不同的集合,所以我应该在存储库中返回什么?域模型和所有相关概念(如聚合、有界上下文、存储库)只处理应用程序的写端。查询端和读取模型独立于域工作。读取模型在后台填充,不受聚合边界的限制。根据API等消费者的要求,同一核心数据结构可以有多个读取模型。如果您想使用repository模式,我建议您创建一个不映射到域模型的不同存储库。
@ApiController
@AllArgsConstructor
public class FilterProfilesController {

    private final UpdateUserLocationUseCase updateUserLocationUseCase;
    private final FilterProfilesUseCase filterProfilesUseCase;

    @PostMapping("/profiles/filter")
    public ResponseEntity<BaseResponse> filterProfiles(@AuthenticationPrincipal AccountId accountId, @RequestBody FilterProfilesRequest request) {
        var userLocation = new Location(new Latitude(request.getLatitude()), new Longitude(request.getLongitude()));

        updateUserLocationUseCase.execute(new UpdateUserLocationUseCase.Command(accountId, userLocation), () -> {
        });
        
        // Conversions from request to value objects (simplified)
        
        var query = new FilterProfilesUseCase.Query(accountId, userLocation, interestedGenders, ageRange, distanceRange);
        var presenter = new FilterProfilesPresenter();

        filterProfilesUseCase.execute(query, presenter);

        return presenter.getViewModel();
    }
}