前言
if...else在每一种语言中都存在,但是代码中如果存在大量的if...else语句,就会造成程序的可读性变差,可维护性变差,进而危害整个系统。同样switch...case也会让代码变得冗余,我们称这样的代码有坏代码的味道,为了优化掉系统中的if...else和switch...case,猫叔做了一个系列,研究可替代方案。这一篇我们重点讲解使用java8中的optional和lambda替换方式。
最近在做后台接口开发时,会通过消息系统处理一些常用的配置数据,在消息发送的时候,会通过判断msgType字段,来区分不同的消息类型,具体的代码如下:
public void handle(String msg) {
try {
if (StringUtils.isNotBlank(msg)) {
MsgInfo msgVo = JSON.parseObject(msg, MsgInfo.class);
switch (msgVo.getType()) {
case 0: //模式新建
modNew(msgVo);
break;
case 1: //模式修改
modUpdate(msgVo);
break;
case 2: //模式删除
modDelete(msgVo);
break;
...
default:
log.info("消息类型不对,不处理消息,message=" + msg);
break;
}
}
} catch (Exception e) {
log.error("消息处理失败,messge=" + msg, e);
MailSender.alertTo("msg消息处理异常", "Msg:" + msg + "," + e.getMessage(), ExceptionUtils.getStackTrace(e));
}
}
以上代码,如果case类型特别多,整个代码看起来特别冗余繁琐。
表驱动法
通过设置一个map,msgType作为key,Consumer
Map, Consumer> action> actionsMap = new HashMap<>();
// 初试配置对应动作
actionsMap.put(value1, (someParams) -> { doAction1(someParams)});
actionsMap.put(value2, (someParams) -> { doAction2(someParams)});
actionsMap.put(value3, (someParams) -> { doAction3(someParams)});
// 省略 null 判断
actionsMap.get(param).accept(someParams);
对上面代码进行重构如下所示:
public Map> consumeMap(MsgInfo msgVo){
Map> map = new HashMap<>();
map.put(0, msgInfo->{ //模式新建
modNew(msgInfo);
});
map.put(1, msgInfo->{ //模式修改
modUpdate(msgInfo);
});
map.put(2, msgInfo->{ //模式删除
modDelete(msgInfo);
});
...
return map;
}
Optional判空
java8为了解决NullPointerException异常,提供了Optional,所以判断msg是否为空时,可以用optional替换,最后handle方法重构后的代码如下:
public void handle(String msg) {
try {
Optional.ofNullable(msg).ifPresent(m -> {
MsgInfo msgVo = JSON.parseObject(m, MsgInfo.class);
Map> map = consumeMap(msgVo);
Consumer consumer = map.get(msgVo.getType());
Optional> optional = Optional.ofNullable(consumer);
optional.ifPresent(c->{
c.accept(msgVo);
});
});
} catch (Exception e) {
log.error("消息处理失败,messge=" + msg, e);
MailSender.alertTo("msg消息处理异常", "Msg:" + msg + "," + e.getMessage(), ExceptionUtils.getStackTrace(e));
}
}
后续会继续介绍其他替换方案。
关注我的微信公众号,更多干货!