首页 > 其他分享 >干掉过多的 if else,让你的代码更优雅

干掉过多的 if else,让你的代码更优雅

时间:2024-01-14 23:26:56浏览次数:19  
标签:case return dealActivity 干掉 优雅 switch else public

干掉过多的 if else,让你的代码更优雅

学习改变命运,技术铸就辉煌。

大家好,我是銘,全栈开发程序员。

写代码时候,有时候条件过多,会有很多 if else ,代码看起来很乱,不够优雅,那如何让代码更优雅呢,如何让代码可读性更强呢,那銘哥就来教你怎么做。

注意啊,是过的 if-else ,如果只是三四个,那就没必要优化了。

image-20240114225917651

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

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

网上有两种见解:

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

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

image-20240114230033405

于是銘哥自己去体验一下,不存在复杂业务逻辑,仅仅比较两种方式的效率:

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

策略+工厂模式

上述说到情况较少时并且业务逻辑不复杂的使用if else可以让代码清晰明了。当每种情况对应的业务逻辑复杂时,建议使用策略+工厂模式。这里我们举个栗子:厂家每个季度要举行不同的活动,我们使用策略工厂模式来实现

策略接口

public interface Strategy {

    /**
     * 处理各种活动
     * @return
     */
    String dealActivity();
}

然后春夏秋冬四季活动类实现该接口

图片

@Service
public 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

@RestController
public class TestController {

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

图片

上述已经干掉了if else ,后续季度活动调整去修改对应活动策略类中逻辑即可。缺点:如果情况比这多,那么策略类会越来越多,也就是所谓的策略类膨胀,并且没有一个地方可以俯视整个业务逻辑

Map+函数式接口

@Service
public class ActivityStrategyService {

    public String dealSpringActivity(){
        return "春季活动逻辑";
    }
    
    public String dealSummerActivity() {
        return "夏季活动逻辑";
    }

    public String dealAutumnActivity() {
        return "秋季活动逻辑";
    }

    public String dealWinterActivity() {
        return "冬季活动逻辑";
    }
}

再写个活动Service

@Service
public 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

@RestController
public 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);
    }
}

标签:case,return,dealActivity,干掉,优雅,switch,else,public
From: https://www.cnblogs.com/songqwu/p/17964424

相关文章

  • Java小细节之缩进中if 和else的对应关系
    importjava.util.Scanner;publicclassMain{publicstaticvoidmain(String[]args){Scannerin=newScanner(System.in);System.out.print("请输入数字:");intn=in.nextInt();System.out.print("请输入分数:");intcount=in.nextInt();if(n==......
  • 用这4招 优雅的实现Spring Boot 异步线程间数据传递
    你好,我是蜗牛!在实际开发中需要在父子线程之间传递一些数据,比如用户登录信息使用ThreadLocal存放保证线程隔离,代码如下:/***@author公众号:woniuxgg*@description用户上下文信息*/publicclassUserUtils{privatestaticfinalThreadLocal<String>userLocal=new......
  • QT开发 2024最新版本优雅的使用vscode开发QT
     ⚔️▬▬▬▬▬▶VS开发QT◀▬▬▬▬▬⚔️ ⚔️先看效果    ⚔️编辑环境变量如图添加环境变量!!!东西全在QT的安装目录!!!找不到的按照我下面的教程再装一次!!! https://blog.csdn.net/lllmeimei/article/details/135502781?spm=1001.2014.3001.5501  ⚔️vscode插件下......
  • Dating Java8系列之巧用Optional之优雅规避NPE问题
    给我馍馍/文  避之不及的NullPointerException NPE:NullPointerException空指针异常是最常见的Java异常之一,抛出NPE错误不是用户操作的错误,而是开发人员的错误,应该被避免,那么只能在每个方法中加入非空检查,阅读性和维护性都比较差。以下是一个常见的嵌套对象:一个用......
  • 优雅的消除if..else,这1条锦囊妙计千万别错过!!
    首先来看一个demo!!publicinterfaceIPay{voidpay();}@ServicepublicclassAliaPayimplementsIPay{@Overridepublicvoidpay(){System.out.println("===发起支付宝支付===");}}@ServicepublicclassWeixinPayim......
  • 优雅处理并发:Java CompletableFuture最佳实践
    第1章:引言大家好,我是小黑,今天,小黑要和大家聊聊CompletableFuture,这个Java8引入的强大工具。在Java传统的Future模式里,咱们都知道,一旦开始了一个异步操作,就只能等它结束,无法知道执行情况,也不能手动完成或者取消。而CompletableFuture呢,就像它的名字一样,是可以"完全控制"的Futur......
  • 优雅而强力地卸载docker-desktop
    DockerDesktop可正常使用打开DockerDesktop,然后点击troubleshoot:再点击uninstall。DockerDesktop不可用[email protected]%sudo/Applications/Docker.app/Contents/MacOS/Docker--uninstallPassword:打不开DockerDesktop且情况二无法解决sud......
  • Spring Boot2.x 优雅停机 Graceful Shutdown
    参考https://www.jianshu.com/p/199e419c025ehttps://blog.csdn.net/u014643282/article/details/116004816gpt注意SpringBoot还支持关闭事件监听,在监听事件内可以编写代码实现关闭前的清理工作。环境环境版本说明Windows10VSCode1.85.1Spring......
  • 在Kubernetes中优雅地导出和清理Ingress资源
    引言Kubernetes的Ingress资源是定义外部访问集群服务的规则。随着微服务架构和容器化技术的普及,Ingress作为路由流量的关键组件变得愈发重要。当我们需要在环境之间迁移Ingress资源或者备份当前的配置时,就会用到导出功能。然而,直接使用kubectl导出可能会包括一些我们不需要的元数......
  • 接手了个项目,被if..else搞懵逼了
    项目会最终沦为屎山,但是作为一个有追求的研发,我们就应当从每个小的ifelse着手,至少让当前这个项目在你维护期间,让其发展成屎山的速度变慢一些,或者能替之前的老前辈还掉一些技术债才是最好的,各位小伙伴你们觉得呢?背景领导:“这个项目,今后就给你维护了啊,仔细点......