我正在研究一个代码逻辑。根据我在下面写的逻辑代码,但我得到了声纳警告,以降低其复杂性。我如何重构下面的代码,将其认知复杂性从59降低到允许的15?
for (int i = 0; i < dataList.getTotalCount(); i++) {
listObj = (TariffRateGroupDTO) dataList.get(i);
if (listObj != null && listObj.getTxnMode().equals("U")) {
if (listObj.getFlightCondition() == null || listObj.getFlightCondition().isEmpty()) {
TariffRateGroupDTO fc = getFlightCondition(listObj.getId(), listObj);
flightCondition = fc.getFlightCondition();
if (flightCondition != null) {
ArrayList obj = (ArrayList) checkFlightCondition(flightCondition);
if (obj != null && !obj.isEmpty()) {
ValidationException ve = new ValidationException();
ValidationError valError = (ValidationError) obj.get(0);
ve.setErrorCode(valError.getMessage() + " at row [" + (i+1) +"]");
throw ve;
}
}
}else {
flightCondition = listObj.getFlightCondition();
if (flightCondition != null) {
ArrayList obj = (ArrayList) checkFlightCondition(flightCondition);
if (obj != null && !obj.isEmpty()) {
ValidationException ve = new ValidationException();
ValidationError valError = (ValidationError) obj.get(0);
ve.setErrorCode(valError.getMessage());
throw ve;
}
}
}
}
}
这部分代码实际上并不那么复杂,可能您的类中还有其他内容。你可以在SonarQube网站上阅读有关认知复杂性及其重要性的信息。
在这里,我给你一些关于如何降低这段代码复杂性的想法(你也可以将它们用于代码的其他部分(:
- 将代码拆分为多个私有方法
- 私有方法可以在类似的情况下重复使用(例如,
if (flightCondition != null)
内部的两个部分都可以用一个以ErrorCode
为参数的方法代替( - 像
obj != null && !obj.isEmpty()
这样的部分可以用一些外部库重写(对于Apache Commons Collections,可以这样做:CollectionUtils.isNotEmpty(obj)
if (flightCondition != null)
可能会移动到checkFlightCondition()
方法中(如果它符合业务逻辑(- 不太相关,但像
listObj.getTxnMode().equals("U")
这样的条件通常可以翻转到"U".equals(listObj.getTxnMode())
,这也将提供隐式的nullsafe检查
p.S.我不会说这段代码中的其他问题(就像其他人在评论中所做的那样(,因为它与问题无关。