🤕告别 if 第一讲(业务断言)共四讲

一、使用背景

在公司进行业务开发中,会涉及到很多的 if else,比如参数校验,数据缺失,逻辑判断等等,会让代码变得十分臃肿且不好维护,于是乎使用一个业务断言工具类,把一些 if 操作抽到断言工具类中(灵感思想来源于Junit Test断言工具),提高代码的可读性和可维护性。

1.1减少 if 语句的使用:提升代码可维护性与可读性

在日常开发中,if 语句是最常见的控制流结构之一。然而,过度使用 if 语句会导致代码冗长、难以理解,尤其是在复杂的业务逻辑中。本文将基于 BizAssert 类的代码示例,讨论如何通过减少 if 语句的使用,来提升代码的可维护性和可读性。

1.2 没有使用BizAssert

每个条件检查都需要手动写一个 if 语句,并且每个 if 语句中都需要重复抛出异常的逻辑。尤其是在多个地方使用相同的检查条件时,代码重复度较高,维护成本增加。

java 复制代码
public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    String text = "";
    Object object = null;

    // 1. 检查集合是否为空
    if (list == null || list.isEmpty()) {
        throw new BusinessException("[断言失败] - 集合不能为空");
    }

    // 2. 检查字符串是否为空
    if (text == null || text.trim().isEmpty()) {
        throw new BusinessException("[断言失败] - 字符串不能为空或空白");
    }

    // 3. 检查对象是否为空
    if (object == null) {
        throw new BusinessException("[断言失败] - 对象不能为空");
    }
}

1.3 使用BizAssert 之后

我们使用 BizAssert 工具类来简化这些条件检查。通过 BizAssert 提供的静态方法,我们可以大大减少冗余代码,提升代码的可读性和可维护性。

java 复制代码
public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    String text = "";
    Object object = null;

    // 使用 BizAssert 进行断言检查

    // 1. 检查集合是否为空
    BizAssert.ifEmpty(list);

    // 2. 检查字符串是否为空
    BizAssert.ifBlank(text);

    // 3. 检查对象是否为空
    BizAssert.ifNull(object);
}

二、开始介绍BizAssert

2.1. 什么是 BizAssert 类?

BizAssert 类是一个用于业务断言的工具类,通过提供一系列的静态方法,来对常见的业务条件进行断言检查。这些断言包括检查布尔表达式、对象、集合、字符串等是否符合特定条件,并在条件不满足时抛出异常。

从代码中可以看出,每个断言方法的实现都包含了一个 if 语句来判断条件是否成立。如果条件成立,则执行相应的处理(通常是抛出异常)。但这种方式往往会导致大量的 if 语句,从而影响代码的整洁性和可读性。

2.2. 为什么要减少 if 语句?

过多的 if 语句不仅让代码变得臃肿,也降低了代码的可读性和可维护性。我们来看几个具体的问题:

  • 代码重复性高 :很多 if 语句执行的操作是重复的,例如异常抛出、错误信息处理等。
  • 代码难以理解 :多个嵌套的 if 语句可能使逻辑变得不清晰,特别是在处理复杂业务规则时。
  • 扩展性差 :如果我们想要扩展新的业务规则或错误处理机制,传统的 if 语句通常需要大规模的修改或新增。

减少 if 语句的使用,可以让我们把业务逻辑抽象成更简洁、易于扩展的形式。

2.3. 改进思路:通过函数式编程降低 if 语句的数量

通过引入函数式编程的思想,我们可以将常见的逻辑提取到可重用的函数中,从而减少 if 语句的数量。例如,在 BizAssert 类中,我们可以用函数式接口来替代部分 if 判断,减少冗余代码。

2.3.1 使用 SupplierRunnable

在代码中,有多个 ifTrueifFalse 方法,它们的功能是根据表达式的值决定是否抛出异常或者执行其他操作。例如:

java 复制代码
public static void ifTrue(boolean expression, Supplier<RuntimeException> exceptionSupplier) {
    if (expression) {
        throw exceptionSupplier.get();
    }
}

这里的 Supplier<RuntimeException> 是一个函数式接口,它允许我们将抛出异常的逻辑延迟到运行时。通过这种方式,我们将 if 语句的执行逻辑从方法内部抽象出来,使得方法本身更加简洁。

类似地,Runnable 接口可以被用来替代执行某些动作的代码块:

java 复制代码
public static void ifTrue(boolean expression, Runnable runnable) {
    if (expression) {
        runnable.run();
    }
}

通过这种方式,我们不仅减少了 if 语句的数量,而且使得代码更加灵活、可扩展。

2.3.2 使用默认值和自定义异常消息

在一些方法中,我们为 ifTrueifFalse 方法提供了默认的异常信息。这样的设计有助于减少代码的重复性,例如:

java 复制代码
public static void ifTrue(boolean expression) {
    ifTrue(expression, "[断言失败] - 此表达式必须为 true");
}

public static void ifFalse(boolean expression) {
    ifFalse(expression, "[断言失败] - 此表达式必须为 false");
}

这些默认值简化了调用者的使用方式,减少了每次调用时都需要传递异常信息的繁琐。

2.3.3 断言失败的统一处理

对于空对象、空集合等检查,我们将这些逻辑统一成了断言方法,例如:

java 复制代码
public static void ifNull(Object object, String message) {
    if (object == null) {
        throw new BusinessException(message);
    }
}

public static void ifEmpty(Collection<?> collection, String message) {
    if (collection == null || collection.isEmpty()) {
        throw new BusinessException(message);
    }
}

这种设计使得我们可以在不同的场景下重用相同的断言逻辑,避免了重复的 if 语句。

三、文章总结

  1. 通过减少 if 语句的数量,尤其是在业务断言类中,我们不仅提高了代码的可读性和可维护性,还提升了代码的扩展性。借助函数式编程和通用方法的抽象,我们将常见的业务逻辑提取到可重用的模块中,减少了重复代码的编写。
  2. 减少 if 语句的使用是提升代码质量的一项有效策略,尤其是在处理复杂业务规则时,能够显著提高代码的整洁度和可理解性。

四、附上代码

java 复制代码
 * @author: bdmcom
 * @createTime: 2024/12/14 20:39
 * @company: <a href="https://www.bdmcom.cn">本当迷博客</a>
 * @description: 业务断言工具类
 */
public class BizAssert {

    private BizAssert() {
    }

    /**
     * 如果为True,则抛出异常
     * @param expression 表达式
     * @param message 异常信息
     */
    public static void ifTrue(boolean expression, String message) {
        if (expression) {
            throw new BusinessException(message);
        }
    }

    /**
     * 如果为True,则抛出异常
     * @param expression 表达式
     * @param exceptionSupplier 异常信息
     */
    public static void ifTrue(boolean expression, Supplier<RuntimeException> exceptionSupplier) {
        if (expression) {
            throw exceptionSupplier.get();
        }
    }

    /**
     * 如果为True,则抛出异常
     * @param expression 表达式
     * @param runnable  函数式接口
     */
    public static void ifTrue(boolean expression, Runnable runnable) {
        if (expression) {
            runnable.run();
        }
    }

    /**
     * 如果为True,则抛出异常
     * @param expression 表达式
     * @param message 异常信息
     * @param params 参数
     */
    public static void ifTrue(boolean expression, String message, Object... params) {
        if (expression) {
            throw new BusinessException(CharSequenceUtil.format(message, params));
        }
    }

    /**
     * 如果为False,则抛出异常
     * @param expression 表达式
     */
    public static void ifTrue(boolean expression) {
        ifTrue(expression, "[断言失败] - 此表达式必须为 true");
    }

    /**
     * 如果为False,则抛出异常
     * @param expression 表达式
     * @param message 异常信息
     */
    public static void ifFalse(boolean expression, String message) {
        if (!expression) {
            throw new BusinessException(message);
        }
    }

    /**
     * 如果为False,则抛出异常
     * @param expression 表达式
     * @param exceptionSupplier 异常信息
     */
    public static void ifFalse(boolean expression, Supplier<RuntimeException> exceptionSupplier) {
        if (!expression) {
            throw exceptionSupplier.get();
        }
    }

    /**
     * 如果为False,则抛出异常
     * @param expression 表达式
     * @param message 异常信息
     * @param params 参数
     */
    public static void ifFalse(boolean expression, String message, Object... params) {
        if (!expression) {
            throw new BusinessException(CharSequenceUtil.format(message, params));
        }
    }

    /**
     * 如果为False,则抛出异常
     * @param expression 表达式
     */
    public static void ifFalse(boolean expression) {
        ifFalse(expression, "[断言失败] - 此表达式必须为 false");
    }

    /**
     * 如果对象为空,则抛出异常
     * @param object 对象
     * @param message 异常信息
     */
    public static void ifNull(Object object, String message) {
        if (object == null) {
            throw new BusinessException(message);
        }
    }

    /**
     * 如果对象为空,则抛出异常
     * @param object 对象
     * @param exceptionSupplier 异常信息
     */
    public static void ifNull(Object object, Supplier<RuntimeException> exceptionSupplier) {
        if (object == null) {
            throw exceptionSupplier.get();
        }
    }

    /**
     * 如果对象为空,则抛出异常
     * @param object 对象
     */
    public static void ifNull(Object object) {
        ifNull(object, "[断言失败] - 此对象不能为空");
    }

    /**
     * 如果对象非空,则抛出异常
     * @param object 对象
     * @param message 异常信息
     */
    public static void ifNotNull(Object object, String message) {
        if (object != null) {
            throw new BusinessException(message);
        }
    }

    /**
     * 如果对象非空,则抛出异常
     * @param object 对象
     * @param exceptionSupplier 异常信息
     */
    public static void ifNotNull(Object object, Supplier<RuntimeException> exceptionSupplier) {
        if (object != null) {
            throw exceptionSupplier.get();
        }
    }

    /**
     * 如果对象非空,则抛出异常
     * @param object 对象
     */
    public static void ifNotNull(Object object) {
        ifNotNull(object, "[断言失败] - 此对象必须为空");
    }

    /**
     * 如果集合为空,则抛出异常
     * @param collection 集合对象
     * @param message 异常信息
     */
    public static void ifEmpty(Collection<?> collection, String message) {
        if (collection == null || collection.isEmpty()) {
            throw new BusinessException(message);
        }
    }

    /**
     * 如果集合为空,则抛出异常
     * @param map Map对象
     * @param message 异常信息
     */
    public static void ifEmpty(Map<?, ?> map, String message) {
        if (map == null || map.isEmpty()) {
            throw new BusinessException(message);
        }
    }

    /**
     * 如果集合为空,则抛出异常
     * @param collection 集合对象
     */
    public static void ifEmpty(Collection<?> collection) {
        ifEmpty(collection, "[断言失败] - 集合不能为空");
    }

    /**
     * 如果Map为空,则抛出异常
     * @param map Map对象
     */
    public static void ifEmpty(Map<?, ?> map) {
        ifEmpty(map, "[断言失败] - Map 不能为空");
    }

    /**
     * 如果集合非空,则抛出异常
     * @param collection 集合对象
     * @param message 异常信息
     */
    public static void ifNotEmpty(Collection<?> collection, String message) {
        if (collection != null && !collection.isEmpty()) {
            throw new BusinessException(message);
        }
    }

    /**
     * 如果Map非空,则抛出异常
     * @param map Map对象
     * @param message 异常信息
     */
    public static void ifNotEmpty(Map<?, ?> map, String message) {
        if (map != null && !map.isEmpty()) {
            throw new BusinessException(message);
        }
    }

    /**
     * 如果集合非空,则抛出异常
     * @param collection 集合对象
     */
    public static void ifNotEmpty(Collection<?> collection) {
        ifNotEmpty(collection, "[断言失败] - 集合必须为空");
    }

    /**
     * 如果Map非空,则抛出异常
     * @param map Map对象
     */
    public static void ifNotEmpty(Map<?, ?> map) {
        ifNotEmpty(map, "[断言失败] - Map 必须为空");
    }

    /**
     * 如果字符串为空,则抛出异常
     * @param text 字符串
     * @param message 异常信息
     */
    public static void ifBlank(String text, String message) {
        if (CharSequenceUtil.isBlank(text)) {
            throw new BusinessException(message);
        }
    }

    /**
     * 如果字符串为空,则抛出异常
     * @param text 字符串
     */
    public static void ifBlank(String text) {
        ifBlank(text, "[断言失败] - 字符串不能为空或空白");
    }

    /**
     * 如果字符串非空,则抛出异常
     * @param text 字符串
     * @param message 异常信息
     */
    public static void ifNotBlank(String text, String message) {
        if (CharSequenceUtil.isNotBlank(text)) {
            throw new BusinessException(message);
        }
    }

    /**
     * 如果字符串非空,则抛出异常
     * @param text 字符串
     */
    public static void ifNotBlank(String text) {
        ifNotBlank(text, "[断言失败] - 字符串必须为空或空白");
    }

    /**
     * 如果字符串为空,则抛出异常
     * @param collection 集合对象
     * @param maxSize 最大长度
     * @param message 异常信息
     */
    public static void ifSizeExceeds(Collection<?> collection, int maxSize, String message) {
        if (collection != null && collection.size() > maxSize) {
            throw new BusinessException(message);
        }
    }

    /**
     * 如果集合大小超过限制,则抛出异常
     * @param collection 集合对象
     * @param maxSize 最大长度
     */
    public static void ifSizeExceeds(Collection<?> collection, int maxSize) {
        ifSizeExceeds(collection, maxSize, "[断言失败] - 集合大小超过限制");
    }

    public static void main(String[] args) {
        BizAssert.ifEmpty(Collections.emptyList(), "集合不能为空");
    }
}
相关推荐
落霞与孤鹭齐飞。。5 分钟前
SSM宠物论坛设计系统
java·服务器·数据库·mysql·毕业设计·课程设计
大地爱5 分钟前
【从0带做】基于Springboot3+Vue3的心理健康预约平台
java
计算机学姐9 分钟前
基于微信小程序的安心陪诊管理系统
java·vue.js·spring boot·后端·mysql·微信小程序·小程序
wclass-zhengge28 分钟前
02内存结构篇(D1_自动内存管理)
java·开发语言·jvm
李少兄41 分钟前
解决后端接口返回Long类型参数导致的精度丢失问题
java
UVCuttt1 小时前
三天急速通关Java基础知识:Day1 基本语法
java·开发语言
YQ91 小时前
代码中使用 Iterable<T> 作为方法参数的解释
java
兔爷眼红了1 小时前
Swift语言的物联网
开发语言·后端·golang
ekskef_sef1 小时前
Nginx—Rewrite
java·数据库·nginx
星迹日1 小时前
数据结构:二叉树
java·数据结构·经验分享·二叉树·