Java 将多个方法流畅地链接到一个流中,而不必使用可选类型的详细信息

Java 将多个方法流畅地链接到一个流中,而不必使用可选类型的详细信息,java,functional-programming,monads,optional,Java,Functional Programming,Monads,Optional,在Spring应用程序中,我倾向于将请求主体放在控制器方法中,并希望通过多个方法调用(一路上返回不同的类型)流畅地传递它,如以下(简化)示例中所示: public ResponseEntity postFoo(@RequestBody final FooDto RequestBody){ 返回Optional.of(requestBody)//Optional .map(映射器::fromDto)//可选 .map(service::insertEntity)//可选 .map(mapper::

在Spring应用程序中,我倾向于将请求主体放在控制器方法中,并希望通过多个方法调用(一路上返回不同的类型)流畅地传递它,如以下(简化)示例中所示:

public ResponseEntity postFoo(@RequestBody final FooDto RequestBody){
返回Optional.of(requestBody)//Optional
.map(映射器::fromDto)//可选
.map(service::insertEntity)//可选
.map(mapper::fromEntity)//可选
.map(dto->ResponseEntity.created(//*…*/).body(dto.build())//可选
.orelsetrow(IllegalStateException::new);
}
正如您所看到的,我很想应用一些FP模式,但可选类并不真正适合这样做,因为所隐含的“可选性”是人为的,并且底层感兴趣的对象从一开始就不应该是空的。因此,最终的异常(希望)永远不会被抛出,或者仅仅调用
Optional::get
也不是一个好的选择,因为Sonarlint抱怨未经检查的get调用,这是理所当然的

是否有任何惯用的方法,甚至可以与vavr或其他FP库结合使用,来表达这样一个方法链,比使用这样的人工可选构造更好?否则,我可能不得不避免这样做,并返回到一个带有十几个变量的经典命令式方法


编辑:如果使用返回
的方法,我尝试使用Optional的方式很容易失控,这使得
Optional不再易读。

执行所需操作的最干净方式是恢复命令式样式,例如:

public ResponseEntity<FooDto> postFoo(final FooDto requestBody) {
    final FooEntity fooEntity = fromDto(requestBody);
    final FooEntity updatedEntity = insertEntity(fooEntity); // should be void?
    final FooDto responseDto = fromEntity(updatedEntity);
    return ResponseEntity.created(/* ... */)
            .body(responseDto)
            .build();
}
public responseenty postFoo(请求主体的最终食物){
最终FooEntity=fromDto(请求主体);
final footentity updatedEntity=insertEntity(footentity);//是否应为空?
最终FooDto responseDto=fromEntity(updatedEntity);
返回ResponseEntity.created(/*…*/)
.机构(负责人)
.build();
}

执行所需操作的最干净方法是恢复到命令式样式,例如:

public ResponseEntity<FooDto> postFoo(final FooDto requestBody) {
    final FooEntity fooEntity = fromDto(requestBody);
    final FooEntity updatedEntity = insertEntity(fooEntity); // should be void?
    final FooDto responseDto = fromEntity(updatedEntity);
    return ResponseEntity.created(/* ... */)
            .body(responseDto)
            .build();
}
public responseenty postFoo(请求主体的最终食物){
最终FooEntity=fromDto(请求主体);
final footentity updatedEntity=insertEntity(footentity);//是否应为空?
最终FooDto responseDto=fromEntity(updatedEntity);
返回ResponseEntity.created(/*…*/)
.机构(负责人)
.build();
}

我同意Naman的观点,在这种情况下,命令式风格可能是最干净的方式

如果您真的想做一些
可选的
样式流,您可以创建自己的类

公共最终类值{
私人最终T值;
//强制使用静态构造的私有构造函数
私有值(T值){
这个值=值;
}
//静态构造函数可选样式
公共静态值(T值){
返回新值(Value);
}

公共价值图(函数我同意Naman的观点,在这种情况下,命令式风格可能是最干净的方式

如果您真的想做一些
可选的
样式流,您可以创建自己的类

公共最终类值{
私人最终T值;
//强制使用静态构造的私有构造函数
私有值(T值){
这个值=值;
}
//静态构造函数可选样式
公共静态值(T值){
返回新值(Value);
}

公共价值地图(功能您的问题中不清楚的是
fromDto
insertEntity
fromtentity
的签名,以及您为什么要返回请求主体类型作为响应?@Naman我添加了一些类似IntelliJ的类型提示,希望能有所帮助。如果您的问题是
或lsetrow
永远不会执行,那么如果
RequestBody
为空,该怎么办?@Christianivicevicca您可以详细说明为什么不喜欢您的代码吗?您的问题中不清楚的是
fromDto
insertEntity
fromtentity
的签名,以及您为什么要返回请求body类型作为响应?@Naman我添加了一些类似的类型提示ar to IntelliJ,希望这能有所帮助。如果你的问题是
orelsetrow
永远不会执行,那么如果
RequestBody
为空怎么办?@Christianivicevicca你能详细说明为什么你不喜欢你的代码吗?