如何解决如何降低此Java方法的圈复杂度
我有下一个Java实现,但是它有SonarQube问题,我不知道如何减少该方法。
if (user.getUserId() != null && user.getEmail() != null
&& user.getName() != null) {
return 1;
} else if (user.getUserId() != null && user.getEmail() != null) {
return 2;
} else if (user.getUserId() != null && user.getName() != null) {
return 3;
} else if (user.getUserId() != null) {
return 4;
} else if (user.getEmail() != null && user.getName() != null) {
return 5;
} else if (user.getName() != null) {
return 6;
} else if (user.getEmail() != null) {
return 7;
} else {
return 0;
}
当用户是用户的Pojo时
class Users {
String userId;
String email;
String name;
//getters and setters...
}
解决方法
责任链模式如何?
public abstract class Handler {
protected Handler next;
public abstract Integer process(User user);
}
Handler checkIdEmailName = new Handler() {
@Override
public Integer process(User user) {
boolean check = false;
if (check) {
return 1;
}else {
return next.process(user);
}
}
};
Handler checkIdEmail = new Handler() {
@Override
public Integer process(User user) {
boolean check = false;
if (check) {
return 1;
}else {
return next.process(user);
}
}
};
checkIdEmailName.next = checkIdEmail;
Integer result = checkIdEmailName.process(new User());
,
将其拆分为其他方法将降低该方法本身的复杂性。 像
if (user.getUserId() != null && user.getEmail() != null
&& user.getName() != null) {
return 1;
} else if (user.getUserId() != null && user.getEmail() != null) {
return 2;
} else if (user.getUserId() != null && user.getName() != null) {
return 3;
} else if (user.getUserId() != null) {
return 4;
} else {
return yourNewMethod();
}
private int yourNewMethod(User user) {
if (user.getEmail() != null && user.getName() != null) {
return 5;
} else if (user.getName() != null) {
return 6;
} else if (user.getEmail() != null) {
return 7;
} else {
return 0;
}
}
,
因此,首先我们应该强调什么是认知复杂性,以及如何降低它。主要是通过提取属于在一起的事物。
使用前四个条件查看您的方法时,它们具有相似性,这是对userId的检查。这意味着您可以轻松地将下面的支票合并到一个分支中。这将更容易掌握,并且为提取提供了一种不错的方法
if (user.getUserId() != null) {
if (user.getEmail() != null
&& user.getName() != null) {
return 1;
} else if (user.getEmail() != null) {
return 2;
} else if (user.getName() != null) {
return 3;
} else {
return 4;
}
} else if (user.getEmail() != null && user.getName() != null) {
return 5;
} else if (user.getName() != null) {
return 6;
} else if (user.getEmail() != null) {
return 7;
} else {
return 0;
}
基于此,您可以像这样进一步轻松地提取
if (user.getUserId() != null) {
return fancyNameForAdditionalUserIdChecks(user);
} else if (user.getEmail() != null && user.getName() != null) {
return 5;
} else if (user.getName() != null) {
return 6;
} else if (user.getEmail() != null) {
return 7;
} else {
return 0;
}
private int fancyNameForAdditionalUserIdChecks(Users user) {
if (user.getEmail() != null
&& user.getName() != null) {
return 1;
} else if (user.getEmail() != null) {
return 2;
} else if (user.getName() != null) {
return 3;
} else {
return 4;
}
}
现在,在第一个if中,我们只有四个主要分支-一个不关心userid为null的情况的开发人员,可以简单地跳过它,并且他不需要处理所有这些分支。如果需要的话,他只有一个条件需要首先检查,其余条件则更容易掌握。
要处理这种情况,您总是应该考虑一下,有人在阅读代码。他将获得什么好处,并且可以减轻您的认知负担,因此以下开发人员将更容易理解。机器永远不会遇到读取我们的代码的问题,但是编写易于人类阅读的代码,这是最困难的部分。
旁注:
我宁愿修改您的Dao方法,在这种情况下,通过提供到dao的参数图,将该逻辑放入dao中,并让dao处理这样的逻辑。例如dao.find(Map<String,Object> params)
,您可以根据可用或不可用的字段进行处理。
这是降低复杂度的代码,
boolean userIdAvailable = user.getUserId() != null;
boolean emailAvailable = user.getEmail() != null;
boolean nameAvailable = user.getName();
short response = checkAll(userIdAvailable,emailAvailable,nameAvailable);
if (response == 0) {
response = checkEmailAndName(emailAvailable,nameAvailable);
if (response == 0) {
checkUserIdAndName(userIdAvailable,nameAvailable);
}
}
short checkAll(boolean userIdAvailable,boolean emailAvailable,boolean nameAvailable) {
return userIdAvailable && emailAvailable && nameAvailable ? 1 : 0;
}
short checkEach(boolean userIdAvailable,boolean nameAvailable) {
short response = 0;
if(userIdAvailable) {
response = 4;
} else if(emailAvailable) {
response = 7;
} else if(nameAvailable) {
response = 6;
}
return response;
}
short checkUserIdAndEmail(boolean emailAvailable,boolean userIdAvailable) {
return userIdAvailable && emailAvailable ? 2 : 0
}
short checkEmailAndName(boolean emailAvailable,boolean nameAvailable) {
return emailAvailable && nameAvailable ? 5 : 0
}
short checkUserIdAndName(boolean userIdAvailable,boolean nameAvailable) {
return userIdAvailable && nameAvailable ? 3 : 0
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。