Java 代码 switch 分支过多,怎么改写比较优雅呢?

2023-01-30 09:34:31 +08:00
 NoKey

一个收到消息,分发给不同的处理方法的代码

消息类型已经有十几种了

使用 switch 来根据消息类型跳转不同的处理方法

这个 switch 看起来就很庞大了

请教一下,有没有很好的方式来重构这种情况的代码呢

谢谢~

5630 次点击
所在节点    程序员
51 条回复
PiersSoCool
2023-01-30 10:52:24 +08:00
别改了
cubecube
2023-01-30 10:53:09 +08:00
大规模用策略模式的时候,代码给别人看的时候容易一坨屎,尤其是还是那种 switch 不稳定,状态可能相互有关联的时候。。。
我个人倾向于不改 switch ,处理逻辑复杂的话,内容包在一个函数里面得了
playtomandjerry
2023-01-30 10:53:34 +08:00
不要整花里胡哨的优化,妈的,自己过段时间都看起来费劲,后面人接手能头疼死。switch 内不要放逻辑,直接抽方法出去,已经是很清晰的写法了,简单明了
shaozelin030405
2023-01-30 10:58:08 +08:00
switch 改成查表法(改成个 map ,根据 key 来看对应哪个情况),然后各个情况可以分成各个方法,好搞
Ciallo
2023-01-30 10:58:13 +08:00
9000 行的方法与 1000 个 if 🐶
jorneyr
2023-01-30 10:58:23 +08:00
可以参考 MyBatis 的 TypeHandlerRegistry 把各种消息的处理器集中注册。
zoharSoul
2023-01-30 11:05:25 +08:00
@ianEros 特别烦这种, 还不如 if else
cwcc
2023-01-30 11:07:51 +08:00
我倒是觉得 switch 没啥不妥,但 switch 从代码缩进层面会缩进两次,使用 if else 也才一次。

如果过多的话,建议建个表,然后循环找表对应的方法。或者直接写个表驱动。

不想想太多的话,你只需要做到,让每个 case 的意义十分明确,case 里面的代码不要写逻辑,只调用一两条外面的方法就行了。
dcncy
2023-01-30 11:14:35 +08:00
各自的方法名与其消息类型保持一致,或者加个前后缀。反射调用方法,两三行代码搞定。
bxb100
2023-01-30 11:17:10 +08:00
* switch 放到工厂类里面, case 的逻辑都抽成类, 注意 SRP
* 使用责任链, 好处是不需要大量的 switch/if, 坏处是不好理解
finab
2023-01-30 11:21:14 +08:00
6 楼的表驱动模式
hyqCrystal
2023-01-30 11:21:27 +08:00
工厂加策略
qua
2023-01-30 11:23:37 +08:00
如果用工厂,创建策略的时候还不是要判断类型一长串 switch ,有区别吗
coala
2023-01-30 11:25:42 +08:00
才十几个, 就这样吧, 几十个了可以用策略模式
potatowish
2023-01-30 11:37:14 +08:00
可以使用策略模式,把不同的消息类型处理逻辑划分到独立的实现类中,这些实现类都实现一个公共接口,每个实现类添加一个枚举类型属性,区分消息类型。最后定义一个策略处理类,获取公共接口下所有实现类的对象,按照每次接收的消息类型过滤得到对应的实现类对象,调用其消息处理方法即可。
Achieve7
2023-01-30 12:20:36 +08:00
这是典型的策略+工厂的场景, 用个 dispatcher 进行分发就好了. 如果能够确定逻辑, 甚至直接拿枚举写也行
fkdog
2023-01-30 12:27:51 +08:00
分情况。
如果 switch 分支内的逻辑很简单,那么 switch 就是最优解,你做成多态并不会优雅到哪里去,分支判断的逻辑塞到各个子类里去的话反而不直观也不好维护。
如果 switch 分支内的逻辑很复杂,涉及到 CRUD 、缓存、RPC 等调用,那么楼上有答案。
levelworm
2023-01-30 12:36:55 +08:00
我感觉 switch 里每项不多的话,还是它最优雅。
jinsongzhao
2023-01-30 12:51:28 +08:00
把一个 switch 分门别类,变成多个 switch 或 if else ,可读性就挺好了。
实在想减少代码,只能创建一个类型值和函数名称的对应表,然后把 switch 替换为通过类型查表得到函数名,然后反射调用。这样语句是少了,类型和函数名也都放在一起,类型和函数对应关系可读性优化了,但是逻辑复杂了,总体可读性其实是下降了。
3dwelcome
2023-01-30 12:52:56 +08:00
我以前写过一篇 switch 的文章,"只有放弃英文代码,写全中文代码,才能支撑起千变万化的需求。", 可惜大家回复太热情,直接进水区了。

单文件太大可以分几个子文件,但 Op 最主要的问题,就是消息的命名方式。

起不好英文函数名字,后续维护就是灾难。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/911506

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX