if else代码优化小技巧

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 在程序开发中,复杂的`if-else`结构不仅影响代码的可读性和维护性,还可能演变成难以理解和修改的“烂代码”。为避免此状况,以下几种常见场景提供了优化策略

在程序开发中,if else是我们经常用到的条件判断语句。在程序逻辑中,免不了会有各种条件的判断,并根据结果执行对应的逻辑。if else的好处就是简单,可读性高。然而,随着判断条件变得复杂,判断条件越来越多,就不那么易读了。在一些老项目中,由于缺乏重构,容易出现if else过多太复杂,导致后来开发者不容易看懂因而不敢大改动,只敢在原来的逻辑上继续叠加if else,恶性循环。有句话叫做量变引起质变,时间久了最后成为一段能跑但看不懂改不动的烂代码。

在变成烂代码之前,趁还没到看不懂的地步,日常开发迭代中可以进行小步优化。下面将讲述几个比较常见的场景以及对应的优化方式。

if 条件判断过长

现象

重构书中的示例:

java

代码解读

复制代码

if (date.before(SUMMER_START) || date.after(SUMMER_END))
    charge = quantity * this.winterRate + this.winterServiceCharge;
else
    charge = quantity * this.summerRate;

该段逻辑中,if的判断条件是两个条件进行逻辑或进行组合,这种代码有个问题,可读性太差,无法理解业务含义。

解决方法

将很长的判断式封装成函数或者定义成宏,并以一个清晰表达意图的名字命名,名字能够体现出业务意义。

java

代码解读

复制代码

if (notSummer(date)) 
    charge = winterCharge(quantity);
else
    charge = summerCharge(quantity);

private boolean notSummer(Date date) {
return date.before(SUMMER_START) || date.after(SUMMER_END);
}

private winterCharge(int quantity) {
    return quantity * this.winterRate + this.winterServiceCharge;
}

private summerCharge(int quantity) {
return quantity * this.summerRate;
}

if 一系列条件测试,返回相同的结果

现象

继续借用重构中的示例:

kotlin

代码解读

复制代码

public String getStuLevel(int score) {
		if (score == 100) {
  			return "A";
  	} else if (score >= 90) {
        return "A";
    } else if (score >= 80) {
        return "B";
    } else if (score >= 70) {
        return "B";
    } else if (score >= 60) {
        return "C";
    } else {
      return "D";
    } 
}

score == 100和score >= 90都是返回A。

解决方法

将返回结果相同的分支进行合并处理。重构后代码如下所示:

kotlin

代码解读

复制代码

public String getStuLevel(int score) {
		if (score == 100 || score >= 90) {
  			return "A";
  	} else if (score >= 80 || score >= 70) {
        return "B";
    } else if (score >= 60) {
        return "C";
    } else {
      return "D";
    } 
}

if else 嵌套过深

现象

还是上个例子

java

代码解读

复制代码

if (condition1) {
    if (condition2) {
        action2();
    } else {
        action1();
    }
} else {
    if (condition2) {
        action2();
    } else {
        action3();
    }
}

这个例子中,if 里面还嵌套了if else。这个例子只是嵌套了两层,就已经不容易读了。真实项目中这个问题严重的多,个人这是对代码 可读性差的重要元凶。

解决方法

提前return。把一些场景提前return掉。优化后的代码如下:

java

代码解读

复制代码

if (condition2) {
    action2();
    return;
}

if (condition1) {
    action1();
    return;
}
action3();

项目中也有很多案例可以参考,if (不为空) {处理业务逻辑} 的可以先判断if (为空), 后面处理业务逻辑的{}就可以去掉了。 还有一些特殊的场景,可以提前return掉,这个需要对业务逻辑比较熟悉,重构时要小心。

显式路由转发

现象

if else中,还有种场景,if else中只有单层,没有嵌套,功能上只是做路由转发作用,这种情况使用if else的方式逻辑上也是很简单。

解决方法

如果想要代码看起来更美观,可以做成隐式映射,隐式映射有两种方法:枚举和Map方式。

枚举示例

来看一段代码

java

代码解读

复制代码

String orderStatusDes;
if ("1".equals(orderStatus)) {
    orderStatusDes = "订单未支付";
} else if ("2".equals(orderStatus)) {
    orderStatusDes = "订单已支付";
} else if ("3".equals(orderStatus)) {
    orderStatusDes = "订单已发货";
} else if ("4".equals(orderStatus)) {
    orderStatusDes = "订单已签收";
} else if ("5".equals(orderStatus)) {
    orderStatusDes = "订单已评价";
}

这段代码中,功能是根据订单状态找到对应的订单状态描述。采用枚举的方式优化如下:

java

代码解读

复制代码

public enum OrderStatusEnum {
    UN_PAID("1","订单未支付"),
    PAIDED("2","订单已支付"),
    SENDED("3","订单已发货"),
    SINGED("4","订单已签收"),
    EVALUATED("5","订单已评价");

    private String status;

    private String statusDes;

    static OrderStatusEnum of(String status) {
        for (OrderStatusEnum statusEnum : OrderStatusEnum.values()) {
            if (statusEnum.getStatus().equals(status)) {
                return statusEnum;
            }
        }
        return null;
    }
}

java

代码解读

复制代码

String orderStatusDes = OrderStatusEnum.of(orderStatus).getStatusDes();

借用枚举的隐式映射特性,这段代码优化后一方面可续性上更加直观,订单状态和状态描述很直接就对应上;另一方面,代码也美观了好多,将映射的逻辑剥离出来放到枚举类中,外部调用一行代码就能解决。

Map映射示例

先来看一段代码

java

代码解读

复制代码

if (param.equals(value1)) {
    doAction1(someParams);
} else if (param.equals(value2)) {
    doAction2(someParams);
} else if (param.equals(value3)) {
    doAction3(someParams);
}
// ...

这段代码中根据value1值类型,路由不同的处理逻辑,来看如何用Map来优化。

java

代码解读

复制代码

/1. 先定义一个 ActionService 接口
public interface ActionService {
    void doAction(Context context);
}

//2. 然后定义 5 个实现类
public class ActionService1 implements ActionService{
    public void doAction(Context context) {
        //do something
    }
}

//3. 加入表中
Map<String, ActionService> actionMap = new HashMap<>();
action.put("code1",new ActionService1());
action.put("code2",new ActionService2());
action.put("code3",new ActionService3());
action.put("code4",new ActionService4());
action.put("code5",new ActionService5());

//4. 调用
actionMap.get(action).doAction(someParams);

如果是spring项目,第3步可以从容器中自动找ActionService的实现类填充Map。


转载来源:https://juejin.cn/post/7329033935492202505

相关文章
|
12月前
|
JSON 前端开发 Java
SpringCloud怎么搭建GateWay网关&统一登录模块
本文来分享一下,最近我在自己的项目中实现的认证服务,目前比较简单,就是可以提供一个公共的服务,专门来处理登录请求,然后我还在API网关处实现了登录拦截的效果,因为在一个博客系统中,有一些地址是可以不登录的,比方说首页;也有一些是必须登录的,比如发布文章、评论等。所以,在网关处可以支持自定义一些不需要登录的地址,一些需要登录的地址,也可以在网关处进行校验,如果未登录,可以返回JSON格式的出参,前端可以进行相关处理,比如跳转到登录页面等。
369 4
|
12月前
|
XML Java API
List与String相互转化的方法有哪些
摘要:本文概述了Java中List转换为String及反之的多种策略。使用`String.join()`可简洁地连接List元素;`StringBuilder`提供灵活控制;Java 8 Stream API收集器简化操作;Apache Commons Lang3的`StringUtils.join()`和Guava的`Joiner.on()`支持外部库的高效转换。
217 2
|
12月前
|
监控 算法 Java
怎么用JDK自带工具进行JVM内存分析
JVM内存分析工具,如`jps`、`jcmd`、`jstat`、`jstack`和`jmap`,是诊断和优化Java应用的关键工具。`jps`列出Java进程,`jcmd`执行诊断任务,如查看JVM参数和线程堆栈,`jstat`监控内存和GC,`jstack`生成线程堆栈信息,而`jmap`则用于生成堆转储文件。这些工具帮助排查内存泄漏、优化内存配置、性能调优和异常分析。例如,`jmap -dump:file=heapdump.hprof &lt;PID&gt;`生成堆转储文件,之后可以用Eclipse Memory Analyzer (MAT)等工具分析。
313 0
|
12月前
|
数据采集 机器学习/深度学习 算法
Python-数据爬取(爬虫)
【7月更文挑战第23天】
157 5
|
12月前
|
Cloud Native 安全 持续交付
云原生技术在现代企业中的应用与挑战
【7月更文挑战第23天】本文深入探讨了云原生技术在现代企业中的广泛应用及其带来的挑战。从容器化、微服务架构到持续集成与持续部署(CI/CD),文章详细分析了这些技术如何促进企业的数字化转型。同时,也指出了企业在采用云原生技术过程中可能遇到的安全、成本和技术适配等挑战,并提供了相应的解决策略。
50 6
|
12月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习在自然语言处理中的应用与挑战
本文深入探讨了深度学习技术在自然语言处理(NLP)领域的应用及其所面临的挑战。通过分析深度学习模型如循环神经网络(RNN)、长短期记忆网络(LSTM)和Transformer架构,本文揭示了这些模型如何促进语言理解、机器翻译、情感分析和文本生成等任务的进步。同时,文章也指出了数据偏差、模型可解释性不足以及资源消耗等关键挑战,并提出了未来研究的方向。
106 3
|
12月前
|
缓存 测试技术 程序员
Python 装饰器怎么用?
Python装饰器是强大的工具,可在不改变原函数的情况下增添功能,如日志记录、性能测试、缓存、权限校验及参数验证。示例展示如何用装饰器自动记录函数调用信息,测量执行时间,缓存计算结果加速,检查用户权限,及确保参数类型正确。装饰器简化功能扩展,提升代码效率、维护性与可读性。 ```markdown # Python装饰器:功能增强利器
158 3
|
12月前
|
机器学习/深度学习 人工智能 搜索推荐
探索人工智能在医疗诊断中的应用
【7月更文挑战第23天】随着人工智能技术的飞速发展,其在医疗领域的应用也日益广泛。本文将深入探讨人工智能在医疗诊断中的具体应用,包括图像识别、疾病预测、个性化治疗等方面。同时,我们也将分析人工智能在医疗诊断中面临的挑战和未来发展趋势。
51 1
|
12月前
|
数据采集 Web App开发 存储
Python-数据爬取(爬虫)
【7月更文挑战第24天】
177 7