如何优化Java多分支if-else代码,降低Sonar认知复杂度?
优化方案:用策略模式消除大量if-else分支
步骤1:定义处理逻辑的函数式接口
先封装属性值的处理行为,让每个属性对应独立的处理逻辑:
@FunctionalInterface private interface AttributeProcessor { void process(String value); }
步骤2:绑定属性名与处理逻辑
用静态Map建立属性名称到对应处理逻辑的映射,替代原有的if-else判断链:
private static final Map<String, AttributeProcessor> ATTRIBUTE_PROCESSORS = Map.of( SERVICE_LEVEL_EXTERNAL_ID, value -> featureCode = value, ATTRIBUTE_DESKTOP_USED, value -> quotaUsage = new BigInteger(value), ATTRIBUTE_INSERTION_TIME, value -> insertTime = transformLongToDateSafely(Long.parseLong(value), MM_dd_yyyy_HHmm, UTC), ATTRIBUTE_ARCHIVED_TIME, value -> archivedTime = transformLongToDateSafely(Long.parseLong(value), MM_dd_yyyy_HHmm, UTC), ATTRIBUTE_LAST_MODIFIED_TIME, value -> lastModifiedTime = transformLongToDateSafely(Long.parseLong(value), MM_dd_yyyy_HHmm, UTC), CUSTOM_EXTERNAL_ID_1, value -> dvQuotaUsage = value, CUSTOM_EXTERNAL_ID_2, value -> mmQuotaUsage = value, LAST_LOGIN_ACCESS_MOBILE, value -> lastMobileLogin = DateUtils.transformDateFormatSafely(value, EEE_MMM_d_HHmmss_zzz_yyyy, MM_dd_yyyy_HHmm, UTC), LAST_LOGIN_ACCESS_PC, value -> lastPCLogin = DateUtils.transformDateFormatSafely(value, EEE_MMM_d_HHmmss_zzz_yyyy, MM_dd_yyyy_HHmm, UTC), LAST_LOGIN_ACCESS_WEB, value -> lastWebLogin = DateUtils.transformDateFormatSafely(value, EEE_MMM_d_HHmmss_zzz_yyyy, MM_dd_yyyy_HHmm, UTC), ATTRIBUTE_LOCATION, value -> dcLocator = value );
步骤3:简化原方法逻辑
遍历属性时直接从Map中获取处理逻辑执行,大幅简化代码:
public void setAttributes(List<UserAttribute> attributes) { this.attributes = attributes; for (UserAttribute attribute : attributes) { String attrName = attribute.getName(); AttributeProcessor processor = ATTRIBUTE_PROCESSORS.get(attrName); if (processor != null) { try { processor.process(attribute.getValue()); } catch (NumberFormatException e) { // 根据业务需求处理转换异常:比如日志记录、设置默认值等 } } } }
优化说明
- 彻底消除冗长的if-else链,代码结构更清晰,认知复杂度显著降低
- 新增属性时只需在Map中添加键值对,符合开闭原则,维护成本更低
- 统一了属性名匹配逻辑(原代码混用
equals和StringUtils.equals,这里通过Map键匹配确保一致性) - 增加异常捕获,避免数值/日期转换失败导致的程序崩溃,提升健壮性
兼容Java 8之前版本的写法:
如果项目使用Java 8以下版本,Map.of不可用,改用静态代码块初始化HashMap:
private static final Map<String, AttributeProcessor> ATTRIBUTE_PROCESSORS = new HashMap<>(); static { ATTRIBUTE_PROCESSORS.put(SERVICE_LEVEL_EXTERNAL_ID, value -> featureCode = value); ATTRIBUTE_PROCESSORS.put(ATTRIBUTE_DESKTOP_USED, value -> quotaUsage = new BigInteger(value)); // 其他属性处理器依次put即可 }
内容的提问来源于stack exchange,提问作者Prabha
相关产品推荐
相关产品推荐

