本文介绍一种基于接口与策略模式的优雅方案,用静态映射表替代重复的 switch-case 分支,实现 hint 提供器的动态分发,提升可扩展性与可维护性。
本文介绍一种基于接口与策略模式的优雅方案,用静态映射表替代重复的 switch-case 分支,实现 hint 提供器的动态分发,提升可扩展性与可维护性。
在数独求解器中,不同提示策略(如 NakedSingle、HiddenPair 等)通常具有统一的方法签名 getHint(...),但逻辑各异。若持续使用 switch (num) 显式调用各静态方法,每新增一种策略就得修改主逻辑——违反开闭原则,且代码臃肿易错。
推荐做法:面向接口编程 + 策略注册表
首先定义统一契约:
interface HintProvider {
Hint getHint(
Map<Cell, Set<Integer>> numberMap,
Board penBoard,
Board pencilBoard,
Board solvedBoard,
Collection<Hint> hints
);
}让每个策略类实现该接口(注意:无需静态方法,改用实例方法更灵活):
智能模型自动切换 V5.0.2 - 多模态感知,自动识别图片/视频/音频/代码/文本任务,切换最优模型。支持图片理解(qwen3-vl-plus)、视频音频(qwen3.5-plus)、代码(glm-5)、Office文档(MiniMax-M2.5)、推理等场景。零感知切换,无需手动操作。
class NakedSingle implements HintProvider {
@Override
public Hint getHint(Map<Cell, Set<Integer>> numberMap,
Board penBoard, Board pencilBoard,
Board solvedBoard, Collection<Hint> hints) {
// 具体实现逻辑
return new Hint("Naked Single found at ...");
}
}
class HiddenPair implements HintProvider {
@Override
public Hint getHint(...) {
// 另一种策略实现
return new Hint("Hidden Pair detected ...");
}
}接着构建不可变策略映射表(Java 9+ 推荐 Map.ofEntries):
private static final Map<Integer, HintProvider> HINT_PROVIDERS = Map.ofEntries(
Map.entry(NAKED_SINGLE, new NakedSingle()),
Map.entry(NAKED_PAIR, new NakedPair()),
Map.entry(NAKED_TRIPLE, new NakedTriple()),
Map.entry(HIDDEN_SINGLE, new HiddenSingle()),
Map.entry(HIDDEN_PAIR, new HiddenPair())
// 新增策略只需在此追加一行,无需改动调用逻辑
);
private HintProvider getHintProvider(int num) {
return Objects.requireNonNull(HINT_PROVIDERS.get(num),
"No HintProvider registered for code: " + num);
}最终调用简洁清晰:
public Hint resolveHint(int num,
Map<Cell, Set<Integer>> numberMap,
Board penBoard, Board pencilBoard,
Board solvedBoard, Collection<Hint> hints) {
HintProvider provider = getHintProvider(num);
return provider.getHint(numberMap, penBoard, pencilBoard, solvedBoard, hints);
}✅ 优势总结:
- ✅ 开闭原则友好:新增策略只需添加实现类 + 注册到 HINT_PROVIDERS,零侵入现有逻辑;
- ✅ 类型安全 & 可测试:每个策略可独立单元测试,编译期检查方法签名一致性;
- ✅ 运行时高效:Map.get() 时间复杂度 O(1),优于线性 switch(尤其 case 数 > 10 时);
- ✅ 支持依赖注入:若策略需构造参数(如配置、服务),可轻松集成 Spring 或手动 DI;
- ⚠️ 注意事项:确保 num 值始终存在于映射表中,建议配合 Objects.requireNonNull 或默认兜底策略(如 NO_HINT_PROVIDER)增强健壮性。
此设计将“选择哪个类”与“执行什么逻辑”彻底解耦,是处理多策略分发的经典范式。

















