前言: 话说写这篇博客已经拖了很久了, 一直没写. 怎么说:懒. 年后回来就没正常过,今儿个怎么想起了写呢? 我能说吃蓝莓吃多了,拉肚子不?
上回书说到使用fluent_validator做有关于逻辑的统一校验,但事已至此, 其实最终由于产品形态不一, 还是没能形成一个校验模板. 不过,有关于fluent这个东西,还是可以一说的.
我最开始, 是希望用注解做基本的输入校验, 而用fluent这个东西,封装一个通用的校验器。 我为什么会这样想呢? 首先: 保险标的,要么是人、要么是物。 当为人的时候, 有几个通用的校验点: 1, 当证件 类 型为身份证, 可不必输入性别和年龄;2,校验投保人和被保人的年龄 ,其余的不说, 至少这两点是很基本的。 而当为物的时候, 通常会有2个基本校验点:1, 当被保标的同投保企业的时候,不必输入标的属性; 2,当标的物同标的时,可不必输入标的物。
所以,我的想法是: 将其公有属性抽象在一个基类中, 编辑一个基于此类的统一校验器。 却结果, too young too simple
让我自己感觉自己很年轻的现象有:
1, 我以为可以抽象的基本属性, 其实并不是每款产品都有,甚至是双数的条件都达不到。 比如说基本输入校验里的 手机 短信校验码, 有的产品不需要, 有的产品需要,这时候,我根本不能在基类的这个字段上让其不能为空
2, 同样是年龄校验, 有的单位是周岁、有的单位是天, 呵呵哒,听说还有按月的
3, 我们当时要做的模板, 和我理解的模板不一样,我理解的是我编辑基础的类,可以复用可以继承。 然而, 由于产品形态的多样性, 我们只需要抽象出基本的 产品开发 步骤和规范即可。 目前的产品形态, 支持不了做更细化的模板封装。

每个需要逻辑校验的产品, 都各自有一个校验器, 而一些公用的方法,被整理为了工具类, 比如说通过身份证号获取性别、年龄等。
虽然说没有做成一个统一公用的校验器, 但对于校验这块内容, 比起之前一堆的if else嵌套在一起,现在显得更为有条理性
其具体应用,可以参考上一篇博客中的链接加以深入理解, 也可以在其GitHub介绍上加以学习。 以下贴以下目前产品中的相应应用:
public class BabyProposalValidator extends ValitatorUtils implements Validator<BabyProposalFacadeDTO> { @Override public boolean accept(ValidatorContext validatorContext, BabyProposalFacadeDTO babyProposalFacadeDTO) { return true; } @Override public void onException(Exception e, ValidatorContext validatorContext, BabyProposalFacadeDTO babyProposalFacadeDTO) { } @Override public boolean validate(ValidatorContext context, BabyProposalFacadeDTO bo) { //投保人校验 Boolean holderFlag = holderValidator(context, bo.getProposalHolderPerson(), 18, null, null); if (holderFlag) { //被保人校验 for (BabyProposalSubjectPersonMasterFacadeDTO subject : bo.getProposalSubjectPersonMasters()) { Boolean subjectFlag = subjectValidator(context, subject, bo.getStartDate()); if (!subjectFlag) { return false; } } return true; } return false; } /** * 被保人校验器 * * @param context 上下文 * @param subject 被保人数据 * @param subjectEndDate 被保人年龄计算截止日期 * @return 通过校验返回true */ private Boolean subjectValidator(ValidatorContext context, BabyProposalSubjectPersonMasterFacadeDTO subject, String subjectEndDate) { Boolean certNoValidateRet = certNoValidator(context, subject.getCertType(), subject.getSex(), subject.getBirthday(), subject.getCertNo(), "被"); if (certNoValidateRet) { if(subject.getCertType()==1){ IDCodeInfo idCodeInfo = getIDCodeInfo(subject.getCertNo()); Integer sex = idCodeInfo.getSex(); subject.setSex(sex.equals(1) ? PolicyEnum.Sex.MALE.getCode() : sex.equals(0) ? PolicyEnum.Sex.FEMALE.getCode() : PolicyEnum.Sex.OTHER.getCode()); subject.setBirthday(LocalDate.parse(idCodeInfo.getBirth()).toDate()); } if (Days.daysBetween(new LocalDate(subject.getBirthday()), new LocalDate()).getDays() < 90) { context.addErrorMsg("被保人出生需满90天"); return false; } if (Years.yearsBetween(new LocalDate(subject.getBirthday()), LocalDate.parse(subjectEndDate.substring(0, 10))).getYears() > 10) { context.addErrorMsg("被保人年龄需小于10周岁"); return false; } return true; } return false; } /** * 投保人校验器 * * @param context 校验上下文 * @param holder 投保人数据 * @param holderAgeMin 投保人最小年龄 * @param holderAgeMax 投保人最大年龄 * @param holderEndDate 计算截止日期 * @return 校验通过返回true */ private Boolean holderValidator(ValidatorContext context, BabyProposalHolderPersonFacadeDTO holder, Integer holderAgeMin, Integer holderAgeMax, Date holderEndDate) { Boolean holderValidateRet = certNoValidator(context, holder.getCertType(), holder.getSex(), holder.getBirthday(), holder.getCertNo(), "投"); if (holderValidateRet) { if(holder.getCertType()==1){ IDCodeInfo idCodeInfo = getIDCodeInfo(holder.getCertNo()); Integer sex = idCodeInfo.getSex(); holder.setSex(sex.equals(1) ? PolicyEnum.Sex.MALE.getCode() : sex.equals(0) ? PolicyEnum.Sex.FEMALE.getCode() : PolicyEnum.Sex.OTHER.getCode()); holder.setBirthday(LocalDate.parse(idCodeInfo.getBirth()).toDate()); } //校验投保人年龄 return holderAgeValidator(context, holder.getBirthday(), holderEndDate, holderAgeMin, holderAgeMax); } return false; } }魔法值是每个产品的不同点, 最开始这些参数都是从外传递的, 呃,后来整个就懒了嘛, 反正每个产品一个校验器,就直接写好了,嘿嘿(心情不好的时候, 写代码很是放纵,反正领导不会看我写博客叨叨,我无敌我怕谁)
使用示例:
Result ret = FluentValidator.checkAll() .on(bo, new BabyProposalValidator()) .doValidate() .result(toSimple()); if (!ret.isSuccess()) { return ResponseBzn.build("-1", ret.getErrors().get(0)); }
备注: 可以设置这个校验器执行的时机(通过when语句),也可以设置一些参数
最近一直在做产品的代码重构和迁移, 发现一个问题: 我格局太小。 就拿这个校验器的封装为例, 我就一心想做一个通用的出来, 但事实上结合到产品形态,我这想法本身就不成熟。
当然,也不能说格局太小, 怎么说呢,也许是经历的太少了。 以前从来没有接触过保险产品, 也没有想到每个保险公司对接的产品都各有风格,甚至是同一保险公司对接的产品都各有风格,在只接触了少数合作公司和少数产品的基础上, 要去做一个通用的东西,总觉得不太现实,涵盖不了一些变态的东西。
总之: 多学习,多努力。 感谢现在的同事给我安排的工作, 因为我在完成的过程中, 对于保险产品的开发流程, 形态变化有了更深的理解。 最后,讲个笑话给大家听: 我也不知道我有一回是买啥了, 然后就告诉我免费送一份保险给我,让我填 信息 , 我了个去, 我一看就填个手机号,姓名,别的都没有了, 心里立马断定这玩意儿不靠谱! ——职业病
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删