最近遇到这样的一个业务场景:赠送卡券活动,参与活动用户有3个等级(level1,level2,level3),卡券有3种类型(card1,card2,card3),每个等级的用户奖励不同。level1赠送card1、level2赠送card1,card2、level3赠送card1,card2,card3。假设我们派发卡券的接口为 getReward(cardType),下面我们简单的写一下为不同level的用户赠送卡券。
public void getReward(int userType){
if(userType==1){
sendCard(card1);
}else if(userType==2){
sendCard(card1);
sendCard(card2);
}else if(userType==3){
sendCard(card1);
sendCard(card2);
sendCard(card3);
}
}
上面用if else 分支的逻辑来处理不同用户的卡券赠送完全是没有问题的,但是观察代码可以发现sendCard(card1)这个操作是每个分支都要操作的,sendCard(card2)操作在分支2,3里面都有出现,那么进行我们第一次代码优化
public void getReward(int userType){
sendCard(card1);
if(userType>=2){
sendCard(card2);
}
if(userType==3){
sendCard(card3);
}
}
上面的代码简洁了很多,减少不必要的分支。我们都知道if else可以转换为switch,当分支比较多的时候switch不仅可以让你更加简洁、易读,而且效率更高(switch...case与if...else的根本区别在于,switch...case会生成一个跳转表来指示实际的case分支的地址,而这个跳转表的索引号与switch变量的值是相等的。从而,switch...case不用像if...else那样遍历条件分支直到命中条件,而只需访问对应索引号的表项从而到达定位分支的目的。)
先在第一段代码的基础上我们进行第二次代码优化
public void getReward(int userType){
switch (type) {
case 1:{sendCard(card1);break;}
case 2:{sendCard(card1);sendCard(card2);break;}
case 3:{sendCard(card1);sendCard(card2);sendCard(card3);break;}
default:break;
}
}
检查一下,switch case break中规中矩没有毛病。但是if else 转为switch case,比起优化1还多了几行代码(更不简洁),有点不够意思。下面开始玩花活,在优化1的代码上进行if else转switch优化
public void getReward(int userType){
switch (type) {
case 3:{sendCard(card3);}
case 2:{sendCard(card2);}
case 1:{sendCard(card1);}
default:break;
}
}
同样先检查一下代码,每个用户等级分支只派发一张卡券,怎么跟业务需求对不上??咦!case分支没有break,有bug???
其实都不是,在这个业务赠卡场景下,高level用户分支操作不break结束掉,继续走下一个分支操作刚好满足我们的业务需求,代码简洁,又能装逼(可读性降低了,可能需要跟代码审核人员解释一下代码)怎么会是bug呢!!
有同学可能会说,这个业务场景可以使用策略模式或者其他等等设计模式来优化,确实没错,但是都不在今天的讨论范围。本文仅仅只是对switch case break的一些思考,借助具体的业务场景来更好的描述想法。
总结:
(1)对游戏规则理解的越透彻,游戏就能玩的越好。同样Java语法的理解程度,和你的编码水平是正相关的
(2)不要被惯性思维switch case一定要记得加break局限到,不break也可以设计出巧妙的代码