作者:dfpkgih | 来源:互联网 | 2023-08-23 07:05
我一直在研究Java流和函数式编程。
想出了一种重写小的“用户登录”代码的方法。
这是我的登录方法;
如果来自查询的用户为null,则在过滤器上处理null指针异常。
public ResponseEntity login(User request) {
User dbUser = userRepo.findByEmail(request.getEmail());
if (!aes.matches(request.getPassword(),dbUser.getPassword()))
return ResponseEntity.status(403).build();
return logUserIn(dbUser);
}
private ResponseEntity logUserIn(User dbUser) {
dbUser.setPassword(null);
jwtHandler.setJwtCOOKIE(dbUser);
return ResponseEntity.ok(dbUser);
}
并通过使用流;
public ResponseEntity login(User request) {
return Stream.of(userRepo.findByEmail(request.getEmail()))
.filter(dbUser -> aes.matches(request.getPassword(),dbUser.getPassword()))
.map(this::logUserIn)
.findFirst()
.orElse(ResponseEntity.status(403).build());
}
private ResponseEntity logUserIn(User dbUser) {
dbUser.setPassword(null);
jwtHandler.setJwtCOOKIE(dbUser);
return ResponseEntity.ok(dbUser);
}
我不知道是否要以这种方式使用流。是吗?
如果我在项目的重要部分使用类似的逻辑,以后会遇到麻烦吗?
如果您以更实用的方式使用if-else
而不是短路它,则可能会感觉更好:
if (!aes.matches(request.getPassword(),dbUser.getPassword())) {
return ResponseEntity.status(403).build();
}
else {
return logUserIn(dbUser);
}
使用Stream / Optional在一条语句中执行等效操作较难阅读且性能较差。
您可能会考虑使findByEmail
返回Optional
的可能性,这对于任何“查找”方法来说都是惯用的。然后,您可以将两种方法结合起来
return userRepo.findByEmail(request.getEmail()).map(dbUser -> {
if (!aes.matches(request.getPassword(),dbUser.getPassword())) {
return ResponseEntity.status(403).build();
}
else {
return logUserIn(dbUser);
}
})... // .orElse(null) / .orElseThrow(...)
,
大多数情况下,您会遇到麻烦。 “根本”的问题是,两种写法都可以作为“最佳选择”来辩护,并且Java社区总体上强烈倾向于第二种形式。出于同样的原因,name_variables_like_this
是个坏主意(社区决定约定为nameThemLikeThis
)。打破常规将意味着您的代码很难被他人阅读,而他人编写的代码对于您来说则更难阅读。另外,当您尝试与其他代码进行交互时,您可能会遇到摩擦。
例如,现在(以及可预见的将来),“ lambdas”(带有::
和->
的东西)不是异常透明的,不是控制流透明的,也不是可变的局部变量透明。
这里只有3种可行的选择:
-
以某种方式编写所有代码,以使这3个透明胶片与从不相关,无论您要编写什么内容。这对我来说听起来是不可能的。即使您以某种方式进行管理,也存在其他库。从java.*
开始,它不是为那种代码风格设计的。
-
混合代码样式,如果您没有立即看到透明胶片是相关的,则使用lambda样式;否则,则使用更为必要的样式(如果您认为可能)。这对我来说听起来很愚蠢。当一个样式可以涵盖所有用例时,为什么要混合两种样式?
-
以lambda样式粘贴,向后弯曲以解决这3个透明胶片所困扰的问题,将其“降级”为AtomicX
变体,并使用此类构造将异常和布尔标志传递给进行休息并继续控制外部等植物的流动。这只是编写丑陋的代码,只是因为您特别迷恋上了崭新的闪亮锤子,并且坚持要把所有问题都当作钉子,不是吗?
那是..试图猜测当您与其他代码和其他程序员进行交互时会发生什么。这个片段,在真空中,只有你吗?嗯,都很好。无论您喜欢哪个社区,与其他代码的摩擦以及保持一致的样式都无关紧要。
,
我在实时代码中使用了Java 8流,对我来说最大的缺点是,当管道中未处理异常时,您将获得堆栈跟踪。
确保它们很好编写,并给您以功能风格编写代码的感觉,但事实是流只是一个外观,因为在精美的API下,您正在处理纯净,丑陋的巨大抽象层Java迭代器,当出现问题(例如未处理异常)时,这变得非常痛苦。
因此,您的问题的答案是是的,您可能会遇到麻烦,但这取决于您对堆栈跟踪的了解程度,其中70%的跟踪与您编写的代码无关已经写过,但是写了一些神奇的东西,用来将迭代器变成流。
尽可能使用if-else
,for-loops
等,除非您确信流将更高效或更易于阅读。值得注意的是,可读性非常重要,Stream
API的存在的部分原因是为了提高可读性,但是在充分利用潜力的同时,节制和良好的判断是值得实践的优点。流API。