一、使用背景
在公司进行业务开发中,会涉及到很多的 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 使用 Supplier
和 Runnable
在代码中,有多个 ifTrue
和 ifFalse
方法,它们的功能是根据表达式的值决定是否抛出异常或者执行其他操作。例如:
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 使用默认值和自定义异常消息
在一些方法中,我们为 ifTrue
和 ifFalse
方法提供了默认的异常信息。这样的设计有助于减少代码的重复性,例如:
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
语句。
三、文章总结
- 通过减少
if
语句的数量,尤其是在业务断言类中,我们不仅提高了代码的可读性和可维护性,还提升了代码的扩展性。借助函数式编程和通用方法的抽象,我们将常见的业务逻辑提取到可重用的模块中,减少了重复代码的编写。 - 减少
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(), "集合不能为空");
}
}