java - 有没有办法简化该源代码?
问题描述
我目前正在使用 Spring Boot 实现公告板 API。我将向您展示的源代码场景是关于公告板或评论修改,
两者都需要在修改前在评论或公告板输入时提交密码。
所以,我只是使用'isBoard'作为输入:隐藏值来执行'boardRepository'中的'findById'并将其与passwordEncoder的匹配函数进行比较,然后更新布尔值。
但是,下面的代码显示重复并使用了相同的逻辑。有没有办法让这更简单?
@Transactional
public boolean tryToUpdateArticleOrReply(Long id, String password, boolean isBoard) throws ApiException {
AtomicBoolean result = new AtomicBoolean(false);
if(isBoard) {
boardRepository.findById(id).ifPresent(
board -> {
result.compareAndSet(passwordEncoder.matches(board.getUserPass(), password), true);
}
);
} else {
replyRepository.findById(id).ifPresent(
reply -> {
result.compareAndSet(passwordEncoder.matches(reply.getUserPass(), password), true);
}
);
}
if(result.get())
return result.get();
throw new ApiException("INVALID_USER_PASS", "you submitted invaild password.", new ApiExceptionData().add("user_pass", password));
}
解决方案
如果您的findById
andgetUserPass
方法来自接口(并且该findById
方法返回getUserPass
来自的接口),那么您可以简单地执行以下操作:
private boolean check(FindByIdInterface repository,
Long id,
String password) {
return repository.findById(id)
.map(result ->
passwordEncoder.matches(
result.getUserPass(), password))
.orElse(false);
}
然后只需在您根据变量 选择repository
要传递的位置调用它。isBoard
isBoard ? boardRepository : replyRepository
如果它们不是来自共享接口,那么您可以有效地“假装”它们使用 java 中的一些功能接口。
/* R = repository type, T = return type of 'findById' */
private <R, T> check(Function<R, Optional<T>> getByIdMapper,
Function<T, String> getUserPassMapper,
R repository,
Long id,
String password) {
return getByIdMapper.apply(repository)
.map(result ->
passwordEncoder.matches(
getUserPassMapper.apply(result),
password))
.orElse(false);
}
然后用类似这样的方式调用它:
if (isBoard) {
return check(BoardRepository::getById,
Board::getUserPass,
boardRepository, id, password);
} else {
// ...
}
请注意,在这两种情况下都不是AtomicBoolean
必需的。
推荐阅读
- swiftui - 如何在 SwiftUI 视图中执行非视图代码
- java - 类 java.lang.String 不能转换为类 java.util.List(java.lang.String 和 java.util.List 位于加载器“bootstrap”的模块 java.base 中)
- angular - 角度“地图”操作员无法触发我的订阅
- java - 如何在我的 getCell 方法中访问元胞数组?(爪哇)
- docker - 如何让带空格的双引号参数与 dockerfile 中的 PowerShell Start-Process 命令一起使用?
- excel - 如何在excel VBA中组合两个不同列的两个不同请求
- python - 如何停止标签超出滚动区域的末端?
- python - Selenium Webdriver 如何抓取文本?
- office-js - 由于 Win32WebViewHost.exe 问题,Office 应用程序无法显示 Web 加载项的任务窗格
- python - 如何在 Ubuntu 16.04 中创建 Python 3.8 虚拟环境