优化Java代码降低SonarQube认知复杂度(33→15)
重构嵌套if导致认知复杂度超标的Java代码
现有Java代码因大量嵌套if条件,导致SonarQube检测出认知复杂度达33,远超允许的阈值15。尝试仅调整try-catch块结构后优化效果未达预期,请求重构以下代码:
原代码
public void retryDrools() throws InterruptedException { String methodName = Thread.currentThread().getStackTrace()[1].getMethodName(); List<JeopardyRepositoryRequest> fetchedJeopardies = null; JepMessage jepMessage = null; JeopardyRepositoryRequest newjepRequest = null; String successStatus = null; String failureMessage = null; Date now = new Date(); String time = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH).format(now); LoggingUtil.LogInfo(className + "." + methodName, "Cron Job retryDrools started at " + time); try { fetchedJeopardies = jeopardyService.getJeopardyByIsDroolsCallSuccessAndJeopardyStatus(STATUS_OPEN, NO); } catch (JeopardyException e) { LoggingUtil.LogError(className + "." + methodName, "Error Occured while fetching jep by isDroolsCallSuccessAndJeopardyStatus"); } for (JeopardyRepositoryRequest retryJepforDroolsCall : fetchedJeopardies) { try { List<CustomerOrder> customerOrderList = jeopardyService.getCustomerOrdersByBanOrCustomerOrderNumber(retryJepforDroolsCall.getBan(), retryJepforDroolsCall.getCustomerOrderNumber()); if (!isEmptyOrNull(retryJepforDroolsCall.getSfdcAccountId()) && !retryJepforDroolsCall.getSfdcAccountId().equalsIgnoreCase("dummy")) { String customerType = jeopardyService.checkIfConsumerTypeIsSMBPots(customerOrderList) ? BUSINESS : INDIVIDUAL; jepMessage = jeopardyService.checkForSFCCase(retryJepforDroolsCall, customerOrderList, customerType); LoggingUtil.LogInfo(className + "." + methodName, "Response from checkForSFCCase " + jepMessage); } if (jepMessage != null && jepMessage.getAdditionalAttributeList() != null && !jepMessage.getAdditionalAttributeList().isEmpty()) { AdditionalAttributeList droolsCallSuccessAttribute = jepMessage.getAdditionalAttributeList().stream() .filter(attr -> "droolscallSuccess".equalsIgnoreCase(attr.getAttributeName())) .findFirst().orElse(null); AdditionalAttributeList droolsCallFailureMessageAttribute = jepMessage.getAdditionalAttributeList().stream() .filter(attr -> "droolsFailure".equalsIgnoreCase(attr.getAttributeName())) .findFirst().orElse(null); if (droolsCallFailureMessageAttribute != null) { failureMessage = droolsCallFailureMessageAttribute.getAttributeValue(); } if (droolsCallSuccessAttribute != null) { successStatus = droolsCallSuccessAttribute.getAttributeValue(); } retryJepforDroolsCall.setAdditionalAttributeList(jepMessage.getAdditionalAttributeList()); LoggingUtil.LogInfo(className + "." + methodName, "Setting droolsCallSuccessAttribute in JeopardyRepositoryReqr" + droolsCallSuccessAttribute + droolsCallFailureMessageAttribute); String sfdcCaseApplicable = (jepMessage.getIsSfdcCaseApplicable() == true) ? YES : NO; retryJepforDroolsCall.setSfdcCaseApplicable(sfdcCaseApplicable); if (isSuccessStatusValid(successStatus) && jepMessage.getIsSfdcCaseApplicable()) { newjepRequest = sfdcCaseCreationAdapter.createOrUpdateCaseinSFDC(retryJepforDroolsCall, jepMessage, "create"); updateSfdcCaseFields(retryJepforDroolsCall, newjepRequest); } genericWrapper.updateJeopardyById(retryJepforDroolsCall); LoggingUtil.LogInfo(className + "." + methodName, "saving jeopardy"); } } catch (Exception e) { LoggingUtil.LogInfo(className + "." + methodName, " Error occurred " + failureMessage + e.getMessage()); } } }
(注:原代码存在拼写错误,如succesgStatus、LiSt等,重构时已修正)
重构后的代码
public void retryDrools() throws InterruptedException { String methodName = Thread.currentThread().getStackTrace()[1].getMethodName(); logJobStart(methodName); List<JeopardyRepositoryRequest> fetchedJeopardies = fetchJeopardies(methodName); if (isEmptyOrNull(fetchedJeopardies)) { return; } for (JeopardyRepositoryRequest jeopardyRequest : fetchedJeopardies) { processSingleJeopardy(jeopardyRequest, methodName); } } private void logJobStart(String methodName) { String time = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH).format(new Date()); LoggingUtil.LogInfo(className + "." + methodName, "Cron Job retryDrools started at " + time); } private List<JeopardyRepositoryRequest> fetchJeopardies(String methodName) { try { return jeopardyService.getJeopardyByIsDroolsCallSuccessAndJeopardyStatus(STATUS_OPEN, NO); } catch (JeopardyException e) { LoggingUtil.LogError(className + "." + methodName, "Error Occured while fetching jep by isDroolsCallSuccessAndJeopardyStatus"); return Collections.emptyList(); } } private void processSingleJeopardy(JeopardyRepositoryRequest jeopardyRequest, String methodName) { try { List<CustomerOrder> customerOrderList = jeopardyService.getCustomerOrdersByBanOrCustomerOrderNumber( jeopardyRequest.getBan(), jeopardyRequest.getCustomerOrderNumber()); JepMessage jepMessage = fetchJepMessageIfValid(jeopardyRequest, customerOrderList, methodName); if (jepMessage == null || isAdditionalAttributesEmpty(jepMessage)) { return; } updateJeopardyAttributes(jeopardyRequest, jepMessage, methodName); handleSfdcCaseCreation(jeopardyRequest, jepMessage, methodName); genericWrapper.updateJeopardyById(jeopardyRequest); LoggingUtil.LogInfo(className + "." + methodName, "saving jeopardy"); } catch (Exception e) { LoggingUtil.LogInfo(className + "." + methodName, " Error occurred " + e.getMessage()); } } private JepMessage fetchJepMessageIfValid(JeopardyRepositoryRequest jeopardyRequest, List<CustomerOrder> customerOrderList, String methodName) { String sfdcAccountId = jeopardyRequest.getSfdcAccountId(); if (isEmptyOrNull(sfdcAccountId) || "dummy".equalsIgnoreCase(sfdcAccountId)) { return null; } String customerType = jeopardyService.checkIfConsumerTypeIsSMBPots(customerOrderList) ? BUSINESS : INDIVIDUAL; JepMessage jepMessage = jeopardyService.checkForSFCCase(jeopardyRequest, customerOrderList, customerType); LoggingUtil.LogInfo(className + "." + methodName, "Response from checkForSFCCase " + jepMessage); return jepMessage; } private boolean isAdditionalAttributesEmpty(JepMessage jepMessage) { return jepMessage.getAdditionalAttributeList() == null || jepMessage.getAdditionalAttributeList().isEmpty(); } private void updateJeopardyAttributes(JeopardyRepositoryRequest jeopardyRequest, JepMessage jepMessage, String methodName) { AdditionalAttributeList successAttr = findAttribute(jepMessage, "droolscallSuccess"); AdditionalAttributeList failureAttr = findAttribute(jepMessage, "droolsFailure"); jeopardyRequest.setAdditionalAttributeList(jepMessage.getAdditionalAttributeList()); LoggingUtil.LogInfo(className + "." + methodName, "Setting droolsCallSuccessAttribute in JeopardyRepositoryReqr" + successAttr + failureAttr); String sfdcCaseApplicable = jepMessage.getIsSfdcCaseApplicable() ? YES : NO; jeopardyRequest.setSfdcCaseApplicable(sfdcCaseApplicable); } private AdditionalAttributeList findAttribute(JepMessage jepMessage, String attributeName) { return jepMessage.getAdditionalAttributeList().stream() .filter(attr -> attributeName.equalsIgnoreCase(attr.getAttributeName())) .findFirst() .orElse(null); } private void handleSfdcCaseCreation(JeopardyRepositoryRequest jeopardyRequest, JepMessage jepMessage, String methodName) { AdditionalAttributeList successAttr = findAttribute(jepMessage, "droolscallSuccess"); if (successAttr == null || !YES.equalsIgnoreCase(successAttr.getAttributeValue()) || !jepMessage.getIsSfdcCaseApplicable()) { return; } JeopardyRepositoryRequest newJepRequest = sfdcCaseCreationAdapter.createOrUpdateCaseinSFDC(jeopardyRequest, jepMessage, "create"); updateSfdcCaseFields(jeopardyRequest, newJepRequest); } private void updateSfdcCaseFields(JeopardyRepositoryRequest jeopardyRequest, JeopardyRepositoryRequest newJepRequest) { if (newJepRequest == null) { return; } if (newJepRequest.getSfdCaseId() != null && newJepRequest.getSfdcCaseNumber() != null) { jeopardyRequest.setSfdcCaseId(newJepRequest.getSfdCaseId()); jeopardyRequest.setSfdcCaseNumber(newJepRequest.getSfdcCaseNumber()); jeopardyRequest.setSfdcCaseCreationStatus(SUCCESS); } else if (newJepRequest.getSfdCaseError() != null) { jeopardyRequest.setSfdcCaseError(newJepRequest.getSfdCaseError()); jeopardyRequest.setSfdcCaseCreationStatus(FAILURE); } } // 空值判断工具方法 private boolean isEmptyOrNull(Object obj) { if (obj == null) { return true; } if (obj instanceof String) { return ((String) obj).trim().isEmpty(); } if (obj instanceof Collection) { return ((Collection<?>) obj).isEmpty(); } return false; }
重构核心措施
- 拆分大方法:将原方法拆分为多个单一职责的小方法(日志记录、数据获取、单条数据处理等),降低单个方法的复杂度
- 提前返回:条件不满足时直接返回,避免嵌套if层级堆积
- 提取重复逻辑:将属性查找、空值判断等重复逻辑封装为独立方法,减少代码冗余
- 简化条件判断:把复杂复合条件拆分为可读性更强的方法调用,减少嵌套深度
- 优化变量处理:避免null初始化,返回空集合替代null,降低空指针风险
内容的提问来源于stack exchange,提问作者A R
相关产品推荐
相关产品推荐

