针对多路分支,可用策略模式(封装同类型动作)、枚举驱动(固定值+类型安全)、Map查表(动态配置)、多态下推(子类自实现)四种方案替代switch,实现判断与执行分离。

当 switch 分支越来越多、每个 case 里逻辑越来越重,代码就容易变“硬编码沼泽”:难测试、难扩展、一改全动。设计模式不是银弹,但针对多路分支,有几种成熟、可落地的替代方案,核心思路是把“判断+执行”拆开——让判断归判断,执行归执行。
用策略模式封装每条分支逻辑
适合场景:不同分支执行的是同一类动作(如计算、校验、转换),只是规则不同。
- 定义统一接口,比如 PaymentHandler,声明
handle(PaymentContext ctx) - 为每种支付方式(Alipay、WeChat、CreditCard)写一个实现类,各自封装完整逻辑
- 运行时通过工厂或配置获取对应 handler,直接调用
handler.handle(ctx),彻底去掉 switch - 新增支付方式?只加一个类 + 注册到工厂,原业务代码零修改
用枚举驱动行为,自带类型安全
适合场景:分支值固定、有限,且和业务语义强绑定(如订单状态、消息类型、审批节点)。
动态切换AI模型以优化成本与性能。当用户发出“eco mode”、“balanced mode”、“smart mode”或“max mode”等模式指令,或使用“/modes status”查询状态及“/modes setup”配置模式时触发。
- 把所有分支值定义为枚举项,例如 OrderStatus { CREATED, PAID, SHIPPED, COMPLETED }
- 在枚举内部直接定义方法,比如
canCancel()或nextStatus(),把状态相关逻辑收进枚举本身 - 调用时直接
order.getStatus().canCancel(),无需外部 switch 判断再分发 - 编译器强制你处理所有枚举值,漏写会报错;IDE 支持跳转和补全,不易拼错
用 Map 查表执行,适合动态或配置化场景
适合场景:分支键可能来自外部(如配置文件、数据库、HTTP 参数),或需要运行时热插拔。
- 声明
Map<string supplier>> handlers</string>或Map<eventcode consumer>></eventcode> - 启动时预注册:
handlers.put("USER_LOGIN", this::onUserLogin) - 执行时
handlers.getOrDefault(eventType, defaultHandler).get() - 支持按需加载、条件注册、甚至从配置中心拉取 key-value 映射,比硬编码 switch 更灵活
用多态把判断下推到对象自身
适合场景:分支依据是对象类型(如不同子类的 Document、Rule、Notification),且它们本该有自己的行为。
- 提取公共父类或接口,定义抽象方法,如
generateReport() - 让每个子类自己实现,NormalReport、SummaryReport、ExportReport 各自决定怎么生成
- 业务层只写
report.generateReport(),JVM 自动调用正确版本 - 完全消除“if (obj instanceof X)”,也避免了类型判断与行为耦合

















