对太多的if-else校验逻辑,提供一种简洁优雅的新思路

前言

作为一位高水准的码农,我们的代码应该就像是我们自己的家一样,简洁而优雅。对代码质量有洁癖。之前有写过if多重逻辑的简化,这篇文章是在前几天,优化那一坨长长的if-else逻辑时,顺带记录跟分享的。以便为大家提供一种新的简洁if-else的思路。

业务场景

我们有一个实体类Example,现在业务需要我们对这个实体类中的一部分字段做一些校验,这些校验涉及一些非空校验和特殊的校验。

// Excel导入的实体类
@Data
public class ExampleImport {
    // 仓库号【校验规则,导入不能为空】
	private String warehouseCode;
	// 商品编码【校验规则,导入不能为空】
	private String skuCode;
	// 货主编码【校验规则,导入不能为空】
	private String ownerCode;
	// 序列号【校验规则,导入不能为空,且 序列号位数不能超过60位】
	private String serialNumber;
	// 状态 【校验规则,导入不能为空,且状态只能为"01" "02" "03"】
	private String serialState;
}

优化之前

// 这个方法是对我们线上的业务走了一个变形。
// 原方法,是一个Excel导入数据的校验,需要对Excel中先做字段的全量校验,
// 把每一行都校验不通过的重新生成一个导入失败的Excel并展示出来。
public String validateImportData(ExampleImport import) {
	if (StringUtils.isEmpty(import.getWarehouseCode())) {
		return "仓库号为空";
	}
	if (StringUtils.isEmpty(import.getSkuCode())) {
		return "商品编码为空";
	}
	if (StringUtils.isEmpty(import.getOwnerCode())) {
		return "货主编码为空";
	}
	if (StringUtils.isEmpty(import.getSerialNumber())) {
		return "序列号为空";
	}
	if (StringUtils.isEmpty(import.getSerialState())) {
		return "状态为空";
	}
	if (import.getSerialNumber().length() > 60) {
		return "序列号长度不能超过60位";
	}
	// 状态校验的字符串逻辑而不是复杂的条件表达式
	if (!"01,02,03".contains(import.getSerialState()+",")) {
		return import.getSerialState().indexOf(",") > 0 ? "序列号状态非法请检查"
			: "序列号状态非法请检查";
	}
	return "";
}

优化之后

public String validateImportData(ExampleImport import) {
	Object[] validateFieldIfNecessary = new Object[]{
		import.getWarehouseCode(),
		import.getSkuCode(),
		import.getOwnerCode(),
		import.getSerialNumber(),
		import.getSerialState(),
		import.getSerialNumber().length() > 60,
		// 状态校验的字符串逻辑而不是复杂的条件表达式
		!"01,02,03".contains(import.getSerialState()+",") &&
		import.getSerialState().indexOf(",") > 0
	};
	String necessaryField = StringUtils.join(validateFieldIfNecessary, ",");

	int index = necessaryField.indexOf("null");
    if (index == -1) {
        // 校验特殊判断信息
        index = necessaryField.indexOf("false");
        return FIELD_VALIDATED_MSG.get(index) == null ? StringUtils.EMPTY : FIELD_VALIDATED_MSG.get(index);
    }

    // 获取不通过校验信息
    return FIELD_VALIDATED_MSG.get(index);
}
// 校验信息的注册[这里可以换成枚举类]:基于表驱动的方式简化if-else
@PostConstructor
private void registerValidatedMsg() {
	FIELD_VALIDATED_MSG.put(0, "仓库号为空");
	FIELD_VALIDATED_MSG.put(1, "商品编码为空");
	FIELD_VALIDATED_MSG.put(2, "货主编码为空");
	FIELD_VALIDATED_MSG.put(3, "序列号为空");
	FIELD_VALIDATED_MSG.put(4, "状态为空");
	FIELD_VALIDATED_MSG.put(5, "序列号长度不能超过60位");
	FIELD_VALIDATED_MSG.put(6, "序列号状态非法请检查");
}

范式总结

写这篇文章的目的是,想给大家提供一个新的思路来减少代码中的if逻辑。这里,我想给大家介绍的是,对于if的非空校验的判断,我们可以将多个字段的校验合并成String字符串,并利用分隔符进行划分字段。此时,需求就转化成对String字符串的基本方法的使用。重要的事情说三遍,对于一些特殊场景,我们会经常用if逻辑。这些if逻辑中有很多,我们可以细思考的进行,比如利用集合中的方法或者String字符串的indexOf方法等。
其次,if条件内的复杂表达式,我们可以进行转换,就比如序列号状态的非法检查。这种取巧的代码,有一个隐患点就是,对于客户端输入,我们需要做特殊处理。比如我上述例子中的import.getSerialState()+","。因为,我们是将复杂的条件表达式进行了String字符串的拼装,并使用了分隔符。切记切记切记

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值