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

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

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

产品需求

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

excel数据模板下载

excel数据导入

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

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

如下:

//第一种

publicResulttest(@RequestBody @Validated TestDTO dto){...}

//第二种

publicResulttest(@RequestBody @Valid TestDTO dto{...}

//第三种

publicResult  test(@RequestBody @Validated(value = {SaveGroup.class})

TestDTO dto){...}

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

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

image-20200809162534227

image-20200809162624232

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

重构开始-开篇

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

代码地址:https://github.com/pengziliu/GitHub-code-practice

image-20200809163432162

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

创建一份Excel数据

image-20200809173342671

PostMan模拟调用数据解析

image-20200809173308231

项目代码和控制台输出

image-20200809173613381

重构开始-实战

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

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

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

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

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

定义返回得数据结构

新建返回对象UserExcelVO.java

image-20200809174433991

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

@PostMapping("/importExcel")

publicUserExcelVOimportExcel(@RequestParam("file")MultipartFile file){

List list =null;

List fail =newArrayList<>();

UserExcelVO userExcelVO =newUserExcelVO();

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

try{

list = EasyExcel.read(file.getInputStream(),UserExcelModel.class,newModelExcelListener()).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();

}

returnuserExcelVO;

}

测试数据:

用户名 年龄 手机号 性别

宝典哥1 11 23847235 男

宝典哥2 12 15813847236 男

宝典哥3 13 15813847237 男

宝典哥4 14 15813847238 男

宝典哥5 15 15813847239 男

宝典哥6 16 15813847240 男

宝典哥7 17 152247241 男

宝典哥8 18 15813847242 男

宝典哥9 19 15813847243 男

宝典哥10 20 15813847244 男

宝典哥11 21 15813847245 男

宝典哥12 22 15813847246 男

宝典哥13 23 15813847247 男

宝典哥14 24 15813847248 男

宝典哥15 25 15813847249 男

测试结果:

{

"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

publicclassValidationUtils{

publicstaticValidatorgetValidator(){

returnvalidator;

}

staticValidator validator;

static{

ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();

validator=validatorFactory.getValidator();

}

}

对Model加注解

image-20200809181934329

对Controller进行改写

@PostMapping("/v2/importExcel")

publicUserExcelVOimportExcelV2(@RequestParam("file")MultipartFile file){

List list =null;

List fail =newArrayList<>();

UserExcelVO userExcelVO =newUserExcelVO();

try{

list = EasyExcel.read(file.getInputStream(),UserExcelModel.class,newModelExcelListener()).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();

}

returnuserExcelVO;

}

测试

对同一组数据进行测试

image-20200809182924261

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

{

"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":"男"

}

]

}

代码仓库

https://github.com/pengziliu/GitHub-code-practice

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

总结

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345