美文网首页
代码优化实战,3行代码解决了一百个if else!

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

作者: 生命在于折腾_355a | 来源:发表于2020-08-12 18:35 被阅读0次

    代码优化实战,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,里面包含很多的项目教程和实例

    总结

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

    相关文章

      网友评论

          本文标题:代码优化实战,3行代码解决了一百个if else!

          本文链接:https://www.haomeiwen.com/subject/xkcydktx.html