1、前言

留神题目是过多的,所以三四个就没必要干掉了。理论开发中咱们常常遇到判断条件很多的状况,比方下图有20多种状况,不必想必定是要优化代码的,须要思考的是如何去优化?

网上很多说用switch case啊,首先不比拟if else与switch case效率问题的,只从代码整洁度来看二者没啥区别啊!咱们这里更重要的是代码整洁度问题,为什么呢?来看下文的比拟。

2、If else与switch case效率真的差距很大么?

网上有两种见解:

第一种是说switch…case会生成一个跳转表来批示理论的case分支的地址,而这个跳转表的索引号与switch变量的值是相等的。从而,switch…case不必像if…else那样遍历条件分支直到命中条件,而只需拜访对应索引号的表项从而达到定位分支的目标。简略来说就是以空间换工夫

第二种是说二者效率上差距并不大

于是咱们本人去体验一下,不存在简单业务逻辑,仅仅比拟两种形式的效率:

    @Test    void contextLoads() {        testIf(100000);        System.gc();        testSwitch(100000);    }    private void testIf(Integer param) {        long start = System.currentTimeMillis();        for (int i = 0; i < param; i++) {            if (i == param-1){                System.out.println("if判断100000次");            }        }        long end = System.currentTimeMillis();        long total = end - start;        System.out.println("Test耗费工夫:" + total);    }    private void testSwitch(Integer param){        long start = System.currentTimeMillis();        for (int i = 0; i < param; i++) {            switch (i){                case 99999:                    System.out.println("switch判断100000次");                    break;            }        }        long end = System.currentTimeMillis();        long total = end - start;        System.out.println("Test耗费工夫:" + total);    }

可见差距并不大。而状况太多的时候谁还会去用if else和switch case呢?上面还是对两种形式的应用场景做简略的剖析:

if else可能把简单的逻辑关系表白得清晰、易懂,容纳了程序执行的各种状况。

switch不适宜业务零碎的理论简单需要,业务一直的变更迭代,一更改需要,条件的复杂度高了,switch有力解决。switch常常遗记写break,预计很多人一不小心就遗记写了。switch…case只能解决case为常量的状况。当状况不大于5种并且繁多变量的值(如枚举),此时咱们就能够应用switch,它的可读性比if条件更清晰。

除了上述说到枚举的这种场景,倡议应用switch,其余集体愚见:只有状况不大于5种就间接应用if else

3、策略+工厂模式

上述说到状况较少时并且业务逻辑不简单的应用if else能够让代码清晰明了。当每种状况对应的业务逻辑简单时,倡议应用策略+工厂模式。这里咱们举个栗子:厂家每个季度要举办不同的流动,咱们应用策略工厂模式来实现

策略接口

public interface Strategy {    /**     * 解决各种流动     * @return     */    String dealActivity();}

而后春夏秋冬四季流动类实现该接口

@Servicepublic class SpringActivity implements Strategy{    @Override    public String dealActivity() {        return "秋季流动逻辑";    }}

策略类工厂

public class StrategyFactory {    public static Strategy execute(Integer levelCode){        Strategy strategy = null;        switch (levelCode){            case 1:                strategy = new SpringActivity();                break;            case 2:                strategy = new SummerActivity();                break;            case 3:                strategy = new AutumnActivity();                break;            case 4:                strategy = new WinterActivity();                break;            default:                throw new IllegalArgumentException("流动编号谬误");        }        return strategy;    }}

而后在service层中传入对应的编码即可 ,我这里省略了service

@RestControllerpublic class TestController {    @PostMapping("/dealActivity")    public String dealActivity(Integer code){        Strategy strategy = StrategyFactory.execute(1);        return strategy.dealActivity();    }}

上述曾经干掉了if else ,后续季度流动调整去批改对应流动策略类中逻辑即可。毛病:如果状况比这多,那么策略类会越来越多,也就是所谓的策略类收缩,并且没有没有一个中央能够仰视整个业务逻辑。

4、Map+函数式接口

将上述策略类全副作为办法

@Servicepublic class ActivityStrategyService {    public String dealSpringActivity(){        return "秋季流动逻辑";    }    public String dealSummerActivity() {        return "冬季流动逻辑";    }    public String dealAutumnActivity() {        return "秋季流动逻辑";    }    public String dealWinterActivity() {        return "夏季流动逻辑";    }}复制代码

再写个流动Service

@Servicepublic class ActivityService {    @Autowired    private ActivityStrategyService activityStrategyService;    @FunctionalInterface    interface ActivityFunction<A>{        //这里能够传参啊,我这里举例用不上参数        //String dealActivity(A a);     String dealActivity();    }    private final Map<Integer, ActivityFunction> strategyMap = new HashMap<>();    /**     * 初始化策略     */    @PostConstruct    public void initDispatcher(){        strategyMap.put(1,()->activityStrategyService.dealSpringActivity());        strategyMap.put(2, ()-> activityStrategyService.dealSummerActivity());        strategyMap.put(3, ()-> activityStrategyService.dealAutumnActivity());        strategyMap.put(4, ()-> activityStrategyService.dealWinterActivity());    }    public String dealActivity(Integer code){        ActivityFunction<Integer> function = strategyMap.get(code);        //这里避免流动编号没匹配上,能够应用断言来判断从而抛出对立异样        return function.dealActivity();    }}复制代码

扭转Controller

@RestControllerpublic class TestController {    @Autowired    private ActivityService activityService;    @PostMapping("/dealActivity")    public String dealActivity(Integer code){//        Strategy strategy = StrategyFactory.execute(1);//        return strategy.dealActivity();        return activityService.dealActivity(code);    }}