数独提示类调用:替代switch语句的更优实现方案咨询
更优替代方案
原代码示例
switch (num) { case NAKED_SINGLE: return NakedSingle.getHint(numberMap, penBoard, pencilBoard, solvedBoard, hints); case NAKED_PAIR: return NakedPair.getHint(numberMap, penBoard, pencilBoard, solvedBoard, hints); case NAKED_TRIPLE: return NakedTriple.getHint(numberMap, penBoard, pencilBoard, solvedBoard, hints); case NAKED_QUAD: return NakedQuad.getHint(numberMap, penBoard, pencilBoard, solvedBoard, hints); case HIDDEN_SINGLE: return HiddenSingle.getHint(numberMap, penBoard, pencilBoard, solvedBoard, hints); case HIDDEN_PAIR: return HiddenPair.getHint(numberMap, penBoard, pencilBoard, solvedBoard, hints); case HIDDEN_TRIPLE: return HiddenTriple.getHint(numberMap, penBoard, pencilBoard, solvedBoard, hints); case HIDDEN_QUAD: return HiddenQuad.getHint(numberMap, penBoard, pencilBoard, solvedBoard, hints); // more cases }
问题说明
上述代码中,num为int类型,所有数独提示类都包含签名一致的getHint方法(返回String类型)。当前实现的痛点是:新增提示类型时,switch语句会持续膨胀,维护成本逐步升高。
替代方案
方案1:枚举+函数式接口
首先定义匹配getHint方法签名的函数式接口:
@FunctionalInterface interface HintProvider { String getHint(Map<Integer, List<Point>> numberMap, int[][] penBoard, int[][][] pencilBoard, int[][] solvedBoard, List<String> hints); }
接着创建枚举,将int常量与对应类的getHint方法绑定:
enum HintType { NAKED_SINGLE(NAKED_SINGLE_VALUE, NakedSingle::getHint), NAKED_PAIR(NAKED_PAIR_VALUE, NakedPair::getHint), NAKED_TRIPLE(NAKED_TRIPLE_VALUE, NakedTriple::getHint), NAKED_QUAD(NAKED_QUAD_VALUE, NakedQuad::getHint), HIDDEN_SINGLE(HIDDEN_SINGLE_VALUE, HiddenSingle::getHint), HIDDEN_PAIR(HIDDEN_PAIR_VALUE, HiddenPair::getHint), HIDDEN_TRIPLE(HIDDEN_TRIPLE_VALUE, HiddenTriple::getHint), HIDDEN_QUAD(HIDDEN_QUAD_VALUE, HiddenQuad::getHint); private final int code; private final HintProvider provider; HintType(int code, HintProvider provider) { this.code = code; this.provider = provider; } public static HintProvider getProvider(int num) { for (HintType type : HintType.values()) { if (type.code == num) { return type.provider; } } throw new IllegalArgumentException("Unknown hint type: " + num); } }
调用时只需一行代码,新增提示类型仅需在枚举中添加项:
return HintType.getProvider(num).getHint(numberMap, penBoard, pencilBoard, solvedBoard, hints);
方案2:Map映射初始化
提前用HashMap建立int值与方法引用的映射:
private static final Map<Integer, HintProvider> HINT_MAP = new HashMap<>(); static { HINT_MAP.put(NAKED_SINGLE, NakedSingle::getHint); HINT_MAP.put(NAKED_PAIR, NakedPair::getHint); HINT_MAP.put(NAKED_TRIPLE, NakedTriple::getHint); HINT_MAP.put(NAKED_QUAD, NakedQuad::getHint); HINT_MAP.put(HIDDEN_SINGLE, HiddenSingle::getHint); HINT_MAP.put(HIDDEN_PAIR, HiddenPair::getHint); HINT_MAP.put(HIDDEN_TRIPLE, HiddenTriple::getHint); HINT_MAP.put(HIDDEN_QUAD, HiddenQuad::getHint); // 新增类型直接添加put语句即可 } // 调用逻辑 return HINT_MAP.get(num).getHint(numberMap, penBoard, pencilBoard, solvedBoard, hints);
这种方式比枚举更灵活,支持运行时动态添加映射,但固定类型场景下枚举的类型安全性更强。
方案3:反射(不推荐)
通过反射根据num匹配类名调用方法,但会带来性能损耗和可读性下降,仅适合特殊场景,一般不建议使用。
内容的提问来源于stack exchange,提问作者Anu
相关产品推荐
相关产品推荐

