如何重构Java代码实现DRY原则?为何动态语言实现更简单?
优化Java中重复的Switch分支逻辑
太懂这种重复代码的痛苦了!动态语言里可能几行就能搞定的逻辑,Java里一不小心就写出一堆重复的switch,后期维护起来简直是噩梦——改一点逻辑就得挨个分支改,还容易漏。好在我们可以用策略模式+函数式接口的组合来彻底解决这个问题,尤其是Java 8及以上版本支持Lambda后,实现起来特别清爽。
第一步:抽象操作接口
先把不同类型的操作(需要ID和不需要ID的)抽象成函数式接口,这样我们就能把控制器方法当作参数传递:
// 无参数的操作(比如create) @FunctionalInterface interface VoidAction { void run(); } // 需要ID参数的操作(比如read、update、destroy) @FunctionalInterface interface IdAction { void run(String id); // 这里假设promptForID()返回String,你可以换成实际的类型 }
第二步:绑定模型与操作
接下来我们给每个模型(author、book)创建一个操作集合,把每个action和对应的控制器方法绑定起来:
import java.util.Map; // 用record封装每个模型的所有操作(Java 16+支持,低版本可以用普通类) record ModelOperations(VoidAction create, IdAction read, IdAction update, IdAction destroy) {} // 全局的模型-操作映射表 private static final Map<String, ModelOperations> MODEL_OPERATIONS = Map.of( "author", new ModelOperations( AuthorController::create, AuthorController::read, AuthorController::update, AuthorController::destroy ), "book", new ModelOperations( BookController::create, BookController::read, BookController::update, BookController::destroy ) );
第三步:简化业务逻辑
现在原来的双层switch可以彻底简化,再也不用重复写分支结构了:
// 先拿到当前模型对应的操作集合 ModelOperations ops = MODEL_OPERATIONS.get(selectedModel); if (ops == null) { // 处理未知模型的情况,比如提示用户输入错误 System.out.println("无效的模型类型:" + selectedModel); return; } // 根据选择的action执行对应操作 switch (selectedAction) { case "create": ops.create().run(); break; case "read": ops.read().run(promptForID()); break; case "update": ops.update().run(promptForID()); break; case "destroy": ops.destroy().run(promptForID()); break; default: System.out.println("无效的操作类型:" + selectedAction); }
这种方案的好处
- 彻底消除重复:以后新增模型(比如"publisher"),只需要在
MODEL_OPERATIONS里加一条记录就行,不用再复制粘贴switch分支 - 维护成本降低:如果某个操作的逻辑要调整,只需要修改对应的控制器方法,或者调整映射里的绑定关系
- 扩展性超强:后续如果要加新的操作类型(比如"search"),只需要给
ModelOperations加对应的接口字段,再调整switch即可
要是你用的Java版本低于16,把record换成普通的POJO类,加上对应的getter方法就可以了,逻辑完全一样。
内容的提问来源于stack exchange,提问作者Blaine Lafreniere
相关产品推荐
相关产品推荐

