本文介绍通过接口抽象与策略映射(如 map 查找)替代重复 switch-case 的设计方法,使 sudoku 提示逻辑更易扩展、可维护性更强,同时保持类型安全与运行效率。
本文介绍通过接口抽象与策略映射(如 map 查找)替代重复 switch-case 的设计方法,使 sudoku 提示逻辑更易扩展、可维护性更强,同时保持类型安全与运行效率。
在实现 Sudoku 求解器的提示系统时,常需根据整型标识符(如 NAKED_SINGLE、HIDDEN_PAIR 等)动态调用对应策略类的 getHint() 方法。原始写法依赖庞大 switch-case,每新增一种提示类型就得修改主逻辑,违反开闭原则,也易引入遗漏或错误。
更优解是采用策略模式(Strategy Pattern):定义统一接口,将各提示逻辑封装为独立实现类,再通过预构建的查找表(如 Map
✅ 步骤一:定义统一策略接口
interface HintProvider {
String getHint(
Map<cell set>> numberMap,
Board penBoard,
Board pencilBoard,
Board solvedBoard,
List<string> hints
);
}</string></cell>
注意:返回类型按原始代码使用 String;若后续需结构化提示(如含坐标、说明、影响格等),建议升级为专用 Hint 类,增强语义表达力。
✅ 步骤二:实现具体策略类(示例)
class NakedSingle implements HintProvider {
@Override
public String getHint(
Map<cell set>> numberMap,
Board penBoard,
Board pencilBoard,
Board solvedBoard,
List<string> hints) {
// 具体 Naked Single 逻辑
return "Naked Single found at R3C5";
}
}
class HiddenPair implements HintProvider {
@Override
public String getHint(
Map<cell set>> numberMap,
Board penBoard,
Board pencilBoard,
Board solvedBoard,
List<string> hints) {
// 具体 Hidden Pair 逻辑
return "Hidden Pair (3,7) in row 2";
}
}
// 其他类同理实现……</string></cell></string></cell>
所有实现类职责单一、无状态(推荐无状态设计,避免共享字段引发并发问题),便于单元测试与复用。
✅ 步骤三:构建策略注册表(推荐静态不可变 Map)
private static final Map<integer hintprovider> HINT_STRATEGIES = Map.ofEntries(
Map.entry(NAKED_SINGLE, new NakedSingle()),
Map.entry(NAKED_PAIR, new NakedPair()),
Map.entry(NAKED_TRIPLE, new NakedTriple()),
Map.entry(NAKED_QUAD, new NakedQuad()),
Map.entry(HIDDEN_SINGLE, new HiddenSingle()),
Map.entry(HIDDEN_PAIR, new HiddenPair()),
Map.entry(HIDDEN_TRIPLE, new HiddenTriple()),
Map.entry(HIDDEN_QUAD, new HiddenQuad())
// 后续新增只需在此追加一行,无需改动调用逻辑
);
private static HintProvider getHintProvider(int strategyCode) {
return HINT_STRATEGIES.getOrDefault(strategyCode,
() -> "Unsupported hint type: " + strategyCode); // 默认兜底策略
}</integer>
⚠️ 注意事项:
- 使用 Map.ofEntries()(Java 9+)或 ImmutableMap(Guava)确保注册表线程安全与不可变性;
- 若需支持动态加载(如插件化提示),可用 ConcurrentHashMap 配合 computeIfAbsent;
- 建议对 strategyCode 做枚举化(如 HintType.NAKED_SINGLE.ordinal()),避免魔法数字,提升可读性与编译期检查能力;
- getOrDefault 提供优雅降级,避免 NullPointerException,比 Objects.requireNonNull() 更适合生产环境。
✅ 最终调用:简洁、清晰、可扩展
public String executeHint(int num) {
HintProvider provider = getHintProvider(num);
return provider.getHint(numberMap, penBoard, pencilBoard, solvedBoard, hints);
}
从此,每新增一种提示策略(例如 X_WING 或 SKYSCRAPER),仅需:
- 实现 HintProvider 接口;
- 在 HINT_STRATEGIES 中注册一行映射;
- (可选)补充对应枚举常量。
主流程零修改,彻底告别“改一处、漏一处”的 switch 维护陷阱。该方案兼具面向对象设计原则、运行时性能(O(1) 查找)与工程可维护性,是处理同类多态分发问题的标准实践。











