背景
最近写代码经常遇到需要大量书写if else的需求,如何处理呢?
比如有一个自己用的小工具,通过websocket对接消息,根据消息的不同状态进行不同的逻辑处理,消息的格式为:
{
"cmd":0,
"data":"里面的内容不能告诉你,除非充值100万"
}
另外还有一个对话机制,对用户的语句进行意图识别以后,需要根据不同意图调用不同的服务,对话对象为:
public class Message{
/*intent可能是查询天气,可能是查询车票,等等*/
private String intent;
private String message;
private String 其他;
}
实现
1、简单实现
老实说,第一反应就是:管他呢!简单实现!
当cmd
的状态仅仅是0时,那就写
if(message.getInteger("cmd"==0)){
/*干一些见不得人的事*/
}
当cmd
的状态仅仅是0-1时,那就写
if(message.getInteger("cmd")==0){
/*干一些见不得人的事*/
}else if(message.getInteger("cmd")==1){
/*干另外一些见不得人的事*/
}
当cmd
的状态到了大于10个时,那就写…写个毛线,我不干了
2、利用Spring Bean
不干可以说,但是代码还是要写,不然没有晚饭吃!
此时突然想到Spring的bean,于是乎,新建一个消息处理器接口:
public interface MeesageHandler{
String process(JSONObject param);
}
然后为每个状态定义一个Bean,并实现上述接口
/*处理{cmd:0,data:""}*/
@Component("cmd=0")
public class Cmd0Handler implements MeesageHandler{
String process(JSONObject param){
/*处理逻辑*/
}
}
/*处理{cmd:1,data:""}*/
@Component("cmd=1")
public class Cmd1Handler implements MeesageHandler{
String process(JSONObject param){
/*处理逻辑*/
}
}
/*处理{cmd:2,data:""}*/
@Component("cmd=2")
public class Cmd1Handler implements MeesageHandler{
String process(JSONObject param){
/*处理逻辑*/
}
}
/*其他的我不想写了*/
定义完处理接口以后,我的处理逻辑就变成了了
@Autowired
ApplicationContext applicationContext;
public String onMessage(JSONObject message){
/*获取状态对应的实现*/
MeesageHandler handler = applicationContext.getBean("cmd=" + message.getInteger("cmd"),MeesageHandler.class);
String result = handler.process(message);
return result ;
}
思考
此时我觉得我可以吃晚饭了,毕竟每新增一个状态时,我只需要新增一个类,加上@Component("cmd=x")
即可,而不需要去更改之前的逻辑,基本上完成了处理逻辑的解耦
但是这种方式只能在Sping下使用,而且参数的类型受限于接口,于是我开始面向百度检索,看看类似框架或者工具的实现,未果!
为了吃晚饭时,可以加个肉,我决定努力一下
于是我写下了第一个注解@Route
,希望可以通过注解自动匹配逻辑(这里致敬@RequestMapping,借鉴于此)
@Route
public class Process{
/*param对象的cmd==0时跳转执行该方法*/
@Route("/cmd/0")
public String state0(JSONObject param){
/*这里写处理逻辑*/
return "我是cmd==0";
}
/*param对象的cmd==1时跳转执行该方法*/
@Route("/cmd/1")
public String state1(JSONObject param){
/*这里写处理逻辑*/
return "我是cmd==1";
}
/*param 对象的cmd==其他值时跳转执行该方法*/
@Route("/cmd/*")
public String state2(JSONObject param){
/*这里写处理逻辑*/
return "我是else";
}
}
而消息入口逻辑就变成了了简简单单的一行代码:
@Autowired
public String onMessage(JSONObject message){
/*会根据message里面的cmd的值调用不同的方法*/
return Route.dispatch(message);
}
写完以后我将其命名为Disroute
,route
表示路由匹配,dis
取自 dispatcher
的dis
前缀,表示分开之意
Disroute能根据对象、json或者map里面的某个属性值分别执行不同的方法,通过方法解耦的方式,避免大量的if else判断,同时支持java se项目和spring项目
文档和开源地址
欢迎提提建议,谢谢!
特别说明
简单的if else其实是很完美的,至少在我看来简洁而逻辑清晰,不必去追求那些各种乱七八糟的模式,存在即说明它有适合的场景,Disroute的初衷也只是为了适应if处理逻辑随着状态数量线性复杂而已,另外一个原因是顺手!