java if 代码优化_代码优化实战,3行代码解决了一百个if else!

事情是这样的,前段时间做代码review的时候,发现项目中有一个方法代码量超鸡儿多,而且大部分都是写的参数校验的代码,得,我们先抓着缕一缕需求先。

产品需求

找到产品要到了需求文档,需求是这样得:

excel数据模板下载

excel数据导入

导入得时候根据模板得校验规则来进行筛选,导入成功得返回成功列表,数据有问题得返回失败列表,失败列表支持数据编辑修正

好吧。看到需求第一眼可能就是第三列有点难度,我们知道,传统得数据校验是在DTO上面加注解

如下:

//第一种

public Result test(@RequestBody @Validated TestDTO dto) {...}

//第二种

public Result test(@RequestBody @Valid TestDTO dto{...}

//第三种

public Result test(@RequestBody @Validated(value = {SaveGroup.class}) TestDTO dto) {...}

TestDTO里面呢会有一些类似 @NotNull、@NotBlank、@Size等校验注解,这里就不列了。

然后再在全局异常拦截那里进行统一封装,使其放回得数据结构尽量保持统一,所以一般还得有一个GlobalExceptionHandle

56bef1dbd63c28f446545fce81f520d6.png

cd7ff4c7215886d5a0c6c6d4aa0e7d8b.png

讲到常见得数据校验,那么我们画风一转,再回来看需求,可见以上需求是不满足得,首先,我们入参是一个文件,也就是用户传得那个excel,我们得先解析文件再进行数据判断,合法得放一个集合,不合法得放一个集合,再者,即使入参是一个数组,这种校验一旦不满足立马进异常处理了,无法返回给前端正确得数据结构,所以引入了我们今天解决这类需求得解决方案。

重构开始-开篇

我们以之前写文章里面得一个项目easyexcel-demo为模板进行代码得改造和编写

32d561e70d6051b86ba76364f29c3e03.png

下载之前做的小demo,运行起来,创建一个工作簿导入数据

创建一份Excel数据

3abf6d0e0baf85fcb615ac7c779145c4.png

PostMan模拟调用数据解析

ad6bfce84ffeb7df28a0bcf9adc8f76b.png

项目代码和控制台输出

a37b2367213b0c47b1ccf413045f10a2.png

重构开始-实战

好吧,上面介绍了一下之前项目得基本读取excel功能,我们就基于以上功能来实现我们开篇所说得需求。

我们对手机号和姓名自定义一下规则:

手机号满足基本手机号规则

姓名非空且不能超过四个字符

返回成功失败两个集合,全部满足得返回到成功,只要有一条不满足得丢入失败列表。

定义返回得数据结构

新建返回对象UserExcelVO.java

46b5952ac9df6cef08abe871157833a3.png

好了,兄弟们,这里我要上同事写的伪代码了。坐好扶稳了!!!

@PostMapping("/importExcel")

public UserExcelVO importExcel(@RequestParam("file") MultipartFile file){

List list = null;

List fail = new ArrayList<>();

UserExcelVO userExcelVO = new UserExcelVO();

String mobieReg = "^[1][3,4,5,7,8][0-9]{9}$$";

try {

list = EasyExcel.read(file.getInputStream(),UserExcelModel.class,new ModelExcelListener()).sheet().doReadSync();

list.forEach(data->{

//处理姓名的校验

if(StringUtils.isEmpty(data.getName())||data.getName().length()> 4 ){

fail.add(data);

return;

}

//处理手机号的校验

if (StringUtils.isEmpty(data.getMobile())|| !data.getMobile().matches(mobieReg)) {

fail.add(data);

return;

}

//以下根据字段多少可能有n个if

});

userExcelVO.setFail(fail);

list.removeAll(fail);

userExcelVO.setSuccess(list);

} catch (IOException e) {

e.printStackTrace();

}

return userExcelVO;

}

测试数据:

用户名年龄手机号性别

宝典哥11123847235男

宝典哥21215813847236男

宝典哥31315813847237男

宝典哥41415813847238男

宝典哥51515813847239男

宝典哥61615813847240男

宝典哥717152247241男

宝典哥81815813847242男

宝典哥91915813847243男

宝典哥102015813847244男

宝典哥112115813847245男

宝典哥122215813847246男

宝典哥132315813847247男

宝典哥142415813847248男

宝典哥152515813847249男

测试结果:

{

"success": [

{

"cellStyleMap": {},

"name": "宝典哥2",

"age": 12,

"mobile": "15813847236",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥3",

"age": 13,

"mobile": "15813847237",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥4",

"age": 14,

"mobile": "15813847238",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥5",

"age": 15,

"mobile": "15813847239",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥6",

"age": 16,

"mobile": "15813847240",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥8",

"age": 18,

"mobile": "15813847242",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥9",

"age": 19,

"mobile": "15813847243",

"sex": "男"

}

],

"fail": [

{

"cellStyleMap": {},

"name": "宝典哥1",

"age": 11,

"mobile": "23847235",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥7",

"age": 17,

"mobile": "152247241",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥10",

"age": 20,

"mobile": "15813847244",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥11",

"age": 21,

"mobile": "15813847245",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥12",

"age": 22,

"mobile": "15813847246",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥13",

"age": 23,

"mobile": "15813847247",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥14",

"age": 24,

"mobile": "15813847248",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥15",

"age": 25,

"mobile": "15813847249",

"sex": "男"

}

]

}

根据测试结果应该是问题不大的,我这里也是模拟一下,但是实际的业务场景,一个excel里面假如是订单数据,最少是几十个字段起步的,难道要写几十个if else ,明显是不合理的,那我们能不能使用注解的方式帮我们解决问题呢,如果使用注解的话应该如何使用呢?

开造!

创建ValidationUtils.java

public class ValidationUtils {

public static Validator getValidator(){

return validator;

}

static Validator validator;

static{

ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();

validator=validatorFactory.getValidator();

}

}

对Model加注解

fb1b92ebd1782a4e84702eae4f85e75a.png

对Controller进行改写

@PostMapping("/v2/importExcel")

public UserExcelVO importExcelV2(@RequestParam("file") MultipartFile file){

List list = null;

List fail = new ArrayList<>();

UserExcelVO userExcelVO = new UserExcelVO();

try {

list = EasyExcel.read(file.getInputStream(),UserExcelModel.class,new ModelExcelListener()).sheet().doReadSync();

list.forEach(data->{

//此处3行代码解决了一百个if else

Set> violations = ValidationUtils.getValidator().validate(data);

if(violations.size()>0){

fail.add(data);

}

});

userExcelVO.setFail(fail);

list.removeAll(fail);

userExcelVO.setSuccess(list);

} catch (IOException e) {

e.printStackTrace();

}

return userExcelVO;

}

测试

对同一组数据进行测试

0b87fb31a35f624461671579b3cdf616.png

测试结果如下,可以发现,两种实现数据输出结果一致

{

"success": [

{

"cellStyleMap": {},

"name": "宝典哥2",

"age": 12,

"mobile": "15813847236",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥3",

"age": 13,

"mobile": "15813847237",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥4",

"age": 14,

"mobile": "15813847238",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥5",

"age": 15,

"mobile": "15813847239",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥6",

"age": 16,

"mobile": "15813847240",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥8",

"age": 18,

"mobile": "15813847242",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥9",

"age": 19,

"mobile": "15813847243",

"sex": "男"

}

],

"fail": [

{

"cellStyleMap": {},

"name": "宝典哥1",

"age": 11,

"mobile": "23847235",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥7",

"age": 17,

"mobile": "152247241",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥10",

"age": 20,

"mobile": "15813847244",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥11",

"age": 21,

"mobile": "15813847245",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥12",

"age": 22,

"mobile": "15813847246",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥13",

"age": 23,

"mobile": "15813847247",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥14",

"age": 24,

"mobile": "15813847248",

"sex": "男"

},

{

"cellStyleMap": {},

"name": "宝典哥15",

"age": 25,

"mobile": "15813847249",

"sex": "男"

}

]

}

代码仓库

最新代码已提交,欢迎star,里面包含很多的项目教程和实例

总结

写代码的时候,除了做功能,应该要考虑代码的扩展性,不然产品说加个功能,我们又得吭哧吭哧写代码,那这样也台悲催了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值