重构含多Switch分支与泛型的Java工具方法方案咨询
重构方案:用策略模式替代Switch分支
1. 定义比较策略接口
先创建一个泛型函数式接口,统一规范所有比较逻辑的方法签名:
@FunctionalInterface interface ComparisonStrategy<T extends Comparable<T>> { boolean compare(T lookupValue, T actualValue, List<T> lookupValues); }
2. 用枚举管理所有比较策略
将原Switch分支中的每一种比较逻辑,封装成枚举的实例,枚举天然适合作为单例策略的容器,方便统一管理:
enum ComparisonCondition { EQUALS((lookupValue, actualValue, lookupValues) -> { if (lookupValue instanceof String && actualValue instanceof String) { return String.valueOf(lookupValue).trim().equalsIgnoreCase(String.valueOf(actualValue).trim()); } return lookupValue.compareTo(actualValue) == 0; }), NOT_EQUALS((lookupValue, actualValue, lookupValues) -> lookupValue.compareTo(actualValue) != 0), LIKE((lookupValue, actualValue, lookupValues) -> StringUtils.containsIgnoreCase(String.valueOf(actualValue), String.valueOf(lookupValue))), NOT_LIKE((lookupValue, actualValue, lookupValues) -> !StringUtils.containsIgnoreCase(String.valueOf(actualValue), String.valueOf(lookupValue))), IN((lookupValue, actualValue, lookupValues) -> lookupValues.stream().anyMatch(lkpValue -> { if (lkpValue instanceof String) { return ((String) lkpValue).trim().compareToIgnoreCase(String.valueOf(actualValue).trim()) == 0; } return lkpValue.compareTo(actualValue) == 0; })), NOT_IN((lookupValue, actualValue, lookupValues) -> lookupValues.stream().noneMatch(lkpValue -> { if (lkpValue instanceof String) { return ((String) lkpValue).trim().compareToIgnoreCase(String.valueOf(actualValue).trim()) == 0; } return lkpValue.compareTo(actualValue) == 0; })); private final ComparisonStrategy<? super Comparable<?>> strategy; <T extends Comparable<T>> ComparisonCondition(ComparisonStrategy<T> strategy) { this.strategy = strategy; } @SuppressWarnings("unchecked") public <T extends Comparable<T>> boolean apply(T lookupValue, T actualValue, List<T> lookupValues) { return ((ComparisonStrategy<T>) strategy).compare(lookupValue, actualValue, lookupValues); } }
3. 重构原compareValues方法
移除Switch分支,替换为枚举查找逻辑,原方法的核心逻辑被简化,认知复杂度大幅降低:
protected static <T extends Comparable<T>> boolean compareValues(T lookupValue, T actualValue, String comparisonCondition, List<T> lookupValues) { String upperCondition = comparisonCondition.toUpperCase(); boolean result; try { ComparisonCondition condition = ComparisonCondition.valueOf(upperCondition); result = condition.apply(lookupValue, actualValue, lookupValues); } catch (IllegalArgumentException e) { if (LOGGER.isDebugEnabled()) { LOGGER.debug(MSG_FORMAT_INVALID_COMPARISON_CONDITION, upperCondition); } result = false; } if (LOGGER.isDebugEnabled()) { String lookupDisplay = Objects.nonNull(lookupValue) ? lookupValue.toString() : lookupValues.stream().map(Object::toString).collect(Collectors.joining(WhlProcessingConstants.SPLIT_COMMA)); LOGGER.debug("Comparing value '{}' with '{}' using comparison condition '{}'.{}Result: {}", actualValue, lookupDisplay, upperCondition, LINE_SEPARATOR, result); } return result; }
4. 新增比较条件的方式
后续需要新增comparisonCondition分支时,仅需在ComparisonCondition枚举中添加一个新实例并实现对应逻辑即可,完全不需要修改原compareValues方法。例如新增GREATER_THAN条件:
GREATER_THAN((lookupValue, actualValue, lookupValues) -> lookupValue.compareTo(actualValue) > 0)
额外优化:复用重复逻辑
将重复出现的字符串比较逻辑抽成工具方法,减少代码冗余:
private static <T extends Comparable<T>> boolean stringEquals(T lkpValue, T actualValue) { return ((String) lkpValue).trim().compareToIgnoreCase(String.valueOf(actualValue).trim()) == 0; }
之后在EQUALS、IN、NOT_IN的策略实现中直接调用该方法即可。
内容的提问来源于stack exchange,提问作者Hitesh Kirtane
相关产品推荐
相关产品推荐

