防御性编程失败,我开始优化我写的多重 if-else 代码

2024-01-06 04:20

本文主要是介绍防御性编程失败,我开始优化我写的多重 if-else 代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 版本
  • 几种常用的优化方式
    • 提前使用 return 返回去除不必要的 else
    • 使用三目运算符
    • 使用枚举
    • 抽取条件判断作为单独的方法
    • 有时候 switch 比 if-else 更加合适
    • 策略模式 + 简单工厂模式
  • 如何优化开头的代码
  • 个人简介

前言

  • 最近防御性编程比较火,不信邪的我在开发中我进行了尝试,然后我写下了如下的代码:
    public static void main(String[] args) {// do somethingif ("满足条件A") {// 查询权限if ("是否具备权限A" && "是否具备权限B") {// 查询配置if ("配置是否开启"){// do something}}}// do something}
  • 不出意外我被逮捕了,组内另外一位同事对我的代码进行了 CodeReview,我的防御性编程编程没有幸运逃脱,被标记上了“多重 if-else ”需要进行优化,至此我的第一次防御性编程失败,开始了优化多重 if-else 之路,下面是我总结出的常用几种优化方式。

版本

  • Java8

几种常用的优化方式

提前使用 return 返回去除不必要的 else

  • 如果我们的代码块中需要使用 return 返回,我们应该尽可能早的使用 return 返回而不是使用 else
  • 优化前
    private static boolean extracted(boolean condition) {if (condition) {// do somethingreturn false;}else {// do somethingreturn true;}}
  • 优化后
    private static boolean extracted(boolean condition) {if (condition) {// do somethingreturn false;}// do somethingreturn true;}

使用三目运算符

  • 一些简单的逻辑我们可以使用三目运算符替代 if-else ,这样可以让我们的代码更加简洁

  • 优化前

        int num = 0;if (condition) {num = 1;} else {num = 2;}
  • 优化后
int num = condition ? 1 : 2;

使用枚举

  • 在某一些场景我们也可以使用枚举来优化多重 if-else 代码,使我们的代码更加简洁、具备更多的可读性和可维护性。

  • 优化前

        String OrderStatusDes;if (orderStatus == 0) {OrderStatusDes = "订单未支付";} else if (orderStatus == 1) {OrderStatusDes = "订单已支付";} else if (orderStatus == 2) {OrderStatusDes = "已发货";} else {throw new Exception("Invalid order status");}
  • 优化后
public enum OrderStatusEnum {UN_PAID(0, "订单未支付"),PAIDED(1, "订单已支付"),SENDED(2, "已发货"),;private final int code;private final String desc;public int getCode() {return code;}public String getDesc() {return desc;}OrderStatusEnum(int index, String desc) {this.code = index;this.desc = desc;}public static OrderStatusEnum getOrderStatusEnum(int orderStatusCode) {for (OrderStatusEnum statusEnum : OrderStatusEnum.values()) {if (statusEnum.getCode() == orderStatusCode) {return statusEnum;}}return null;}
}// 当然你需要根据业务场景对异常值做出合适的处理
OrderStatusEnum.getOrderStatusEnum(2)

抽取条件判断作为单独的方法

  • 当我们某个逻辑条件判断比较复杂时,可以考虑将判断条件抽离为单独的方法,这样可以使我们主流程逻辑更加清晰
  • 优化前
        // do somethingif ("满足条件A" && "满足条件B") {// 查询权限if ("是否具备权限A" && "是否具备权限B") {// do something}}// do something
  • 优化后
    public static void main(String[] args) {// do somethingif (hasSomePermission()) {// do something}// do something}private static boolean hasSomePermission() {if (!"满足条件A" || !"满足条件B") {return false;}// 查询权限return "是否具备权限A" && "是否具备权限B";}

有时候 switch 比 if-else 更加合适

  • 当条件为清晰的变量和枚举、或者单值匹配时,switch 比 if-else 更加合适,可以我们带好更好的可读性以及更好的性能 O(1)
  • 优化前
if (day == Day.MONDAY) {// 处理星期一的逻辑
} else if (day == Day.TUESDAY) {// 处理星期二的逻辑
} else if (day == Day.WEDNESDAY) {// 处理星期三的逻辑
} else if (day == Day.THURSDAY) {// 处理星期四的逻辑
} else if (day == Day.FRIDAY) {// 处理星期五的逻辑
} else if (day == Day.SATURDAY) {// 处理星期六的逻辑
} else if (day == Day.SUNDAY) {// 处理星期日的逻辑
} else {// 处理其他情况
}
  • 优化后
// 使用 switch 处理枚举类型
switch (day) {case MONDAY:// 处理星期一的逻辑break;case TUESDAY:// 处理星期二的逻辑break;// ...default:// 处理其他情况break;
}

策略模式 + 简单工厂模式

  • 前面我们介绍一些常规、比较简单的优化方法,但是在一些更加复杂的场景(比如多渠道对接、多方案实现等)我们可以结合一些场景的设计模式来实现让我们的代码更加优雅和可维护性,比如策略模式 + 简单工厂模式。

  • 优化前

    public static void main(String[] args) {// 比如我们商场有多个通知渠道// 我们需要根据不同的条件使用不同的通知渠道if ("满足条件A") {// 构建渠道A// 通知} else if ("满足条件B") {// 构建渠道B// 通知} else {// 构建渠道C// 通知}}
// 上面的代码不仅维护起来麻烦同时可读性也比较差,我们可以使用策略模式 + 简单工厂模式
  • 优化后
import java.util.HashMap;
import java.util.Map;// 定义通知渠道接口
interface NotificationChannel {void notifyUser(String message);
}// 实现具体的通知渠道A
class ChannelA implements NotificationChannel {@Overridepublic void notifyUser(String message) {System.out.println("通过渠道A发送通知:" + message);}
}// 实现具体的通知渠道B
class ChannelB implements NotificationChannel {@Overridepublic void notifyUser(String message) {System.out.println("通过渠道B发送通知:" + message);}
}// 实现具体的通知渠道C
class ChannelC implements NotificationChannel {@Overridepublic void notifyUser(String message) {System.out.println("通过渠道C发送通知:" + message);}
}// 通知渠道工厂
class NotificationChannelFactory {private static final Map<String, Class<? extends NotificationChannel>> channelMap = new HashMap<>();static {channelMap.put("A", ChannelA.class);channelMap.put("B", ChannelB.class);channelMap.put("C", ChannelC.class);}public static NotificationChannel createChannel(String channelType) {try {Class<? extends NotificationChannel> channelClass = channelMap.get(channelType);if (channelClass == null) {throw new IllegalArgumentException("不支持的通知渠道类型");}return channelClass.getDeclaredConstructor().newInstance();} catch (Exception e) {throw new RuntimeException("无法创建通知渠道", e);}}
}// 客户端代码
public class NotificationClient {public static void main(String[] args) {// 根据条件选择通知渠道类型String channelType = "A";// 使用简单工厂创建通知渠道NotificationChannel channel = NotificationChannelFactory.createChannel(channelType);// 执行通知channel.notifyUser("这是一条通知消息");}
}
  • 有时候我们还可以借助 Spring IOC 能力的自动实现策略类的导入,然后使用 getBean() 方法获取对应的策略类实例,可以根据我们的实际情况灵活选择。

如何优化开头的代码

  • 好了现在回到开头,如果是你会进行怎么优化,下面是我交出的答卷,大家也可以在评论区发表自己的看法,欢迎一起交流:
   public static void main(String[] args) {// do somethingif (isMeetCondition()) {// 查询配置// 此处查询配置的值需要在具体的任务中使用,所有并没抽离if ("配置是否开启") {// do something}}// do something}/*** 判断是否满足执行条件*/private static boolean isMeetCondition() {if (!"满足条件A") {return false;}// 查询权限return "是否具备权限A" && "是否具备权限B";}

个人简介

👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.

🚀 我对技术的热情是我不断学习和分享的动力。我的博客是一个关于Java生态系统、后端开发和最新技术趋势的地方。

🧠 作为一个 Java 后端技术爱好者,我不仅热衷于探索语言的新特性和技术的深度,还热衷于分享我的见解和最佳实践。我相信知识的分享和社区合作可以帮助我们共同成长。

💡 在我的博客上,你将找到关于Java核心概念、JVM 底层技术、常用框架如Spring和Mybatis 、MySQL等数据库管理、RabbitMQ、Rocketmq等消息中间件、性能优化等内容的深入文章。我也将分享一些编程技巧和解决问题的方法,以帮助你更好地掌握Java编程。

🌐 我鼓励互动和建立社区,因此请留下你的问题、建议或主题请求,让我知道你感兴趣的内容。此外,我将分享最新的互联网和技术资讯,以确保你与技术世界的最新发展保持联系。我期待与你一起在技术之路上前进,一起探讨技术世界的无限可能性。

📖 保持关注我的博客,让我们共同追求技术卓越。

这篇关于防御性编程失败,我开始优化我写的多重 if-else 代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/575194

相关文章

Python实现文件下载、Cookie以及重定向的方法代码

《Python实现文件下载、Cookie以及重定向的方法代码》本文主要介绍了如何使用Python的requests模块进行网络请求操作,涵盖了从文件下载、Cookie处理到重定向与历史请求等多个方面,... 目录前言一、下载网络文件(一)基本步骤(二)分段下载大文件(三)常见问题二、requests模块处理

vscode保存代码时自动eslint格式化图文教程

《vscode保存代码时自动eslint格式化图文教程》:本文主要介绍vscode保存代码时自动eslint格式化的相关资料,包括打开设置文件并复制特定内容,文中通过代码介绍的非常详细,需要的朋友... 目录1、点击设置2、选择远程--->点击右上角打开设置3、会弹出settings.json文件,将以下内

PyCharm接入DeepSeek实现AI编程的操作流程

《PyCharm接入DeepSeek实现AI编程的操作流程》DeepSeek是一家专注于人工智能技术研发的公司,致力于开发高性能、低成本的AI模型,接下来,我们把DeepSeek接入到PyCharm中... 目录引言效果演示创建API key在PyCharm中下载Continue插件配置Continue引言

SQL Server使用SELECT INTO实现表备份的代码示例

《SQLServer使用SELECTINTO实现表备份的代码示例》在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误,在SQLServer中,可以使用SELECTINT... 在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误。在 SQL Server 中,可以使用 SE

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

python实现pdf转word和excel的示例代码

《python实现pdf转word和excel的示例代码》本文主要介绍了python实现pdf转word和excel的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、引言二、python编程1,PDF转Word2,PDF转Excel三、前端页面效果展示总结一

在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码

《在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码》在MyBatis的XML映射文件中,trim元素用于动态添加SQL语句的一部分,处理前缀、后缀及多余的逗号或连接符,示... 在MyBATis的XML映射文件中,<trim>元素用于动态地添加SQL语句的一部分,例如SET或W

使用C#代码计算数学表达式实例

《使用C#代码计算数学表达式实例》这段文字主要讲述了如何使用C#语言来计算数学表达式,该程序通过使用Dictionary保存变量,定义了运算符优先级,并实现了EvaluateExpression方法来... 目录C#代码计算数学表达式该方法很长,因此我将分段描述下面的代码片段显示了下一步以下代码显示该方法如