我是Java的新手,这个 noob 功能一直困扰着我。我已经下载了sonarLint和lo,并且发现它在我的脸上抛出了这个问题 方法的认知复杂度不应太高 。我知道它看起来很丑陋,但是谁能指出我该如何重新格式化以具有干燥的概念并且不像SonarLint所提到的那样具有很高的复杂性。
@PostMapping("/adduser")
// @PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<MessageResponse> registerUser(@Valid @RequestBody SignupRequest signUpRequest) {
/*
* This controller Creates new user based on all the entities for the user
*
*/
if(dbValue)
{
if (repository.existsByUsername(signUpRequest.getUsername())) {
return ResponseEntity
.badRequest()
.body(new MessageResponse("Error: Username is already taken!"));
}
if (repository.existsByEmail(signUpRequest.getEmail())) {
return ResponseEntity
.badRequest()
.body(new MessageResponse("Error: Email is already in use!"));
}
// Create new user's account
User2 user = new User2(signUpRequest.getUsername(),
signUpRequest.getEmail(),
signUpRequest.getCustomername(),
signUpRequest.getCustomerid(),
signUpRequest.getDescription(),
encoder.encode(signUpRequest.getPassword()));
Set<String> strRoles = signUpRequest.getRoles();
Set<Role2> roles = new HashSet<>();
Role2 e = new Role2();
e.setName("ROLE_ADMIN");
roles.add(e);
user.setRoles(roles);
repository.save(user);
}
else {
if (repository.existsByUsername(signUpRequest.getUsername())) {
return ResponseEntity
.badRequest()
.body(new MessageResponse("Error: Username is already taken!"));
}
if (repository.existsByEmail(signUpRequest.getEmail())) {
return ResponseEntity
.badRequest()
.body(new MessageResponse("Error: Email is already in use!"));
}
// Create new user's account
User1 user = new User1(signUpRequest.getUsername(),
signUpRequest.getEmail(),
signUpRequest.getCustomername(),
signUpRequest.getCustomerid(),
signUpRequest.getDescription(),
encoder.encode(signUpRequest.getPassword()));
Set<String> strRoles = signUpRequest.getRoles();
Set<Role> roles = new HashSet<>();
if (strRoles == null) {
Role userRole = roleRepository1.findByName(URole.ROLE_USER)
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
roles.add(userRole);
} else {
strRoles.forEach(role -> {
switch (role) {
case "admin":
Role adminRole = roleRepository1.findByName(URole.ROLE_ADMIN)
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
roles.add(adminRole);
break;
default:
Role userRole = roleRepository1.findByName(URole.ROLE_USER)
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
roles.add(userRole);
}
});
}
user.setRoles(roles);
repository.save(user);
}
return ResponseEntity.ok(new MessageResponse("User Added successfully!"));
}
赞赏批评和任何帮助。预先感谢。
答案 0 :(得分:3)
Optional check(Predicate condition, String message)
或将此方法委托给新的验证实用程序类。if (repository.existsByUsername(signUpRequest.getUsername()))
return ResponseEntity
.badRequest() // below, you always create a new string and a new message response, use a constant as not to clog the memory
.body(new MessageResponse("Error: Username is already taken!"));
if (repository.existsByEmail(signUpRequest.getEmail()))
return ResponseEntity
.badRequest() // here too
.body(new MessageResponse("Error: Email is already in use!"));
signUpRequest.getRoles()
可能会返回一个Optional;如果为空,则返回Collections.emptyList()
,而不是null Role userRole = roleRepository1.findByName(URole.ROLE_USER)
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
roles.add(userRole);
使用
roleRepository1.findByName(URole.ROLE_USER).ifPresent(roles::add);
答案 1 :(得分:2)
只需始终如一地应用Extract Method,它将大大改善您的代码。这样做还将帮助您发现责任并为进一步的重构铺平道路。
您可以按原样使用现有代码,然后将其拆分为较小的自描述方法,以使主要算法更易于理解。
例如
if (repository.existsByUsername(signUpRequest.getUsername())) {
return usernameTakenError();
}
if (repository.existsByEmail(signUpRequest.getEmail())) {
return emailUsedError();
}
user = userToSignup(signUpRequest);
userRepository.save(user);
return ResponseEntity.ok(new MessageResponse("User Added successfully!"));
在这一点上,如何真正实现这些方法并不重要:核心算法仍然简短易懂。
请注意,我经常自动将异常转换为响应错误,这允许以声明的方式检查规则 例如
//throws if taken and a generic exception handler
//returns and error response
assertUsernameFree();
还要寻找干燥的机会。例如,而不是:
roleRepository1.findByName(role).orElseThrow(() -> new RuntimeException("Error: Role is not found."));
您可能会抛出roleRepository1.roleOfName(role)
或findExistingByName
而不是返回Optional
。
此外,您的代码的整个角色映射部分太复杂了,我认为其中可能存在一个错误:default
切换情况下,由于USER_ROLE
而添加了任何未知角色,对我来说真的没有任何意义。
我希望有更多类似的东西(可能在resolveSignupRoles
函数中,甚至可能是两次分派的signUpRequest.getRoles(rolesRepo)
):
Set<Role> roles = signUpRequest.getRoles().stream()
.map(r -> URole.fromCode(r))
.map(r -> userRepository::roleOfName).collect(Collectors.toSet());
if (roles.isEmpty()) roles.add(userRepository.roleOfName(URole.ROLE_USER));
这里有大量的重构机会,但是Extract Method易于应用,并且会立即改善您编写的所有代码。