先来一道开胃菜。

public class XXService {... private Boolean isTax(PurchaseBillItem purchaseBillItem) {if (purchaseBillItem.getIsTax() == null) {throw new BizException("是否是税标志isTax不能为空");}if (purchaseBillItem.getIsTax() == 0) {// 不是税return false;}if (purchaseBillItem.getIsTax() == 1) {//是税return true;}return true;}...}//调用 isTax if (!isTax(purchaseBillItem)) {...}

尝尝这么写香不香。(将is_tax从int改为tinyint(1))
  |
  |
 V

public class PurchaseBillItem {...public boolean isTax() {return isTax;}...}

再来看一个。

    /*** 判断进项税科目** @param vo* @param adCreateFeeRequestVO* @return 0:进项税科目22210113  1:进项税科目22210114   -1:无*/private String purchaseUpdateInputTax(AdCreateRequestVO vo, AdCreateFeeRequestVO adCreateFeeRequestVO) {if ("0".equals(vo.getCompanyArea())       //境内&& "1".equals(vo.getCompanyTaxPayerNature())) { //一般纳税人if ("1".equals(vo.getSupplierArea())) {  //供应商为境外return "1";} else { //供应商为境内if ("1".equals(vo.getSupplierTaxPayerNature())) { //供应商为一般纳税人return "0";} else if ("2".equals(vo.getSupplierTaxPayerNature())) { //小规模//需判断发票类型if ("1".equals(adCreateFeeRequestVO.getInvoiceType())) { //增值税专用发票return "0";}}}}return "-1";}

宁可用一堆魔数加注释都舍不得定义几个常量。当然,更合适的方式是将这些equals判断放入vo中,然后给方法起一个符合业务的名字,比如 getSubjectOfInputTax()。

接下来换个口味。

    /*** 生成分录明细信息列表** @param subjectCode         科目编码* @param dcFlag              借贷方向* @param adCreateRequestVO   凭证请求对象* @param amount              金额* @param entrySeq            分录行号* @param accountDocumentInfo 凭证信息* @param abstrctRule         摘要规则* @return*/private List<AdAccountDocumentDetailPO> populateDocumentDetails(String subjectCode, Integer dcFlag, AdCreateRequestVO adCreateRequestVO, BigDecimal amount, int entrySeq, AdAccountDocumentInfoPO accountDocumentInfo, DataDicPO abstrctRule) {List<AdAccountDocumentDetailPO> accountDocumentDetails = new ArrayList<AdAccountDocumentDetailPO>();AdAccountDocumentDetailPO accountDocumentDetail;String remark = "";if (AdConstants.SPECIAL_ACC_SUBJECT_CODE_FEES.equals(subjectCode)) { //特殊科目:0List<AdCreateFeeRequestVO> fees = this.getFeesForVoucherType(adCreateRequestVO, accountDocumentInfo.getVoucherType());if (CollectionUtils.isEmpty(fees)) {log.info("凭证生成时,会计科目配置为0,但缺少明细行数据");throw new BizException("凭证生成时,缺少明细行数据");}Map<Long, AdAccountDocumentDetailPO> feeMap = new HashMap<Long, AdAccountDocumentDetailPO>();//费用行对应的分录for (AdCreateFeeRequestVO fee : fees) {BigDecimal feeAmount = fee.getAmount();log.info("费用行数据详情:{}", JSON.toJSONString(fee));String actualSubjectCode = "";if (BillTypeKindConstants.BILL_TYPE_KIND_PURCHASE.equals(adCreateRequestVO.getBillTypeKind())) {Map<String, Object> temp = purchaseHandler(adCreateRequestVO, accountDocumentInfo, fee, dcFlag);feeAmount = (BigDecimal) temp.get("feeAmount");actualSubjectCode = temp.get("actualSubjectCode").toString();} else {actualSubjectCode = adAccountRuleService.getSubjectCodeByFee(fee.getFeeItemsCode(), fee.getDeptType(), fee.getAssetFlag());if (StringUtils.isEmpty(actualSubjectCode)) {log.error("特殊科目0处理时,按费用行生成分录时没有找到对应的会计科目,feeItemCode={}, deptType={}, assetFlag={}", fee.getFeeItemsCode(), fee.getDeptType(), fee.getAssetFlag());throw new BizException(MessageFormat.format("费用行[{0}]部门类型[{1}-{2}]未找到对应会计科目", fee.getFeeItemsCode(), fee.getDeptType(), "10".equals(fee.getDeptType()) ? "管理" : "销售"));}}//特殊处理参数 借款核销单行上部门取一级部门名称if (!StringUtils.isEmpty(fee.getDeptNameLong())) {this.filterRequestParams(accountDocumentInfo.getVoucherType(), adCreateRequestVO, fee, adCreateRequestVO.getDepts());}//构造摘要信息log.info("本次生成摘要===1");remark = this.buildAbstract(adCreateRequestVO, fee, abstrctRule);accountDocumentDetail = this.adAccountDocumentDetailService.populateDocumentDetail(actualSubjectCode, dcFlag, adCreateRequestVO, feeAmount, entrySeq++, accountDocumentInfo, remark);//按费用行生成分录时辅助核算项有可能与行有关accountDocumentDetail.setFee(fee);accountDocumentDetail.setFeeJson(JSON.toJSONString(fee));accountDocumentDetails.add(accountDocumentDetail);//应付,id不为空时,记录凭证详情,供后续使用if (AmountTypeEnum.BILL_AMOUNT.getVoucherType().equals(accountDocumentInfo.getVoucherType()) && fee.getId() != null) {feeMap.put(fee.getId(), accountDocumentDetail);}}adCreateRequestVO.setFeeMap(feeMap);} else if (AdConstants.SPECIAL_ACC_SUBJECT_CODE_BANK.equals(subjectCode)) { //特殊科目:1String companyCode = adCreateRequestVO.getCompanyCode(); //公司String accNo = adCreateRequestVO.getPayerAccNo(); //账号//为关联方交易if ("0".equals(adCreateRequestVO.getRelatedParty())) {//收款凭证if (AmountTypeEnum.COLLECT_AMOUNT.getVoucherType().equals(accountDocumentInfo.getVoucherType())) {log.info("特殊科目为1且为收款凭证,公司编码取供应商对应公司编码,账号取收款账号...");companyCode = adCreateRequestVO.getSupplierCompanyCode();accNo = adCreateRequestVO.getPayeeAccNo();}}//关联方交易付款凭证和之前流程一样log.info("获取公司对应的银行科目 cf_ad_company_acc_subject.SUBJECT_CODE");String actualSubjectCode = adAccountRuleService.getSubjectCodeByCompanyCode(companyCode, accNo);if (StringUtils.isEmpty(actualSubjectCode)) {log.error("特殊科目1处理时,按公司没有找到对应的银行会计科目,companyCode={}, 支付账号={}", companyCode, accNo);throw new BizException(MessageFormat.format("公司[{0}]没找到对应的银行会计科目", companyCode));}log.info("本次生成摘要===2");remark = this.buildAbstract(adCreateRequestVO, null, abstrctRule);accountDocumentDetail = this.adAccountDocumentDetailService.populateDocumentDetail(actualSubjectCode, dcFlag, adCreateRequestVO, amount, entrySeq++, accountDocumentInfo, remark);accountDocumentDetails.add(accountDocumentDetail);} else if (AdConstants.SPECIAL_ACC_SUBJECT_CODE_TEMP.equals(subjectCode)) { //特殊科目:2//为验收单生成凭证使用String actualSubjectCode;List<AdCreateDetailAmountRequestVO> detailAmountRequestVOS = adCreateRequestVO.getDetailAmounts();if (CollectionUtils.isEmpty(detailAmountRequestVOS)) {log.info("凭证生成时,会计科目配置为2,但缺少金额明细数据");throw new BizException("凭证生成时,缺少金额明细数据");}for (AdCreateDetailAmountRequestVO amountRequestVO : detailAmountRequestVOS) {actualSubjectCode = adAccountRuleService.getSubjectCodeByFee(amountRequestVO.getFeeItemsCode(), null, amountRequestVO.getAssetFlag());if (StringUtils.isEmpty(actualSubjectCode)) {log.error("特殊科目2处理时,按费用行生成分录时没有找到对应的会计科目,feeItemCode={},assetFlag={}", amountRequestVO.getFeeItemsCode(), amountRequestVO.getAssetFlag());throw new BizException(MessageFormat.format("金额明细行[{0}]没找到对应的会计科目", amountRequestVO.getFeeItemsName()));}//构造摘要信息log.info("本次生成摘要===4");AdCreateFeeRequestVO tempFee = new AdCreateFeeRequestVO();BeanUtils.copyProperties(amountRequestVO, tempFee);remark = this.buildAbstract(adCreateRequestVO, tempFee, abstrctRule);accountDocumentDetail = this.adAccountDocumentDetailService.populateDocumentDetail(actualSubjectCode, dcFlag, adCreateRequestVO, amountRequestVO.getAmount(), entrySeq++, accountDocumentInfo, remark);accountDocumentDetail.setFee(tempFee);accountDocumentDetail.setFeeJson(JSON.toJSONString(amountRequestVO));accountDocumentDetails.add(accountDocumentDetail);}} else {AdCreateFeeRequestVO fee = null;if (AmountTypeEnum.DEPOSIT_LOAN_AMOUNT.getVoucherType().equals(accountDocumentInfo.getVoucherType())) {//借款核销单的押金类型 摘要特殊处理,取任一押金行的供应商,其他字段不使用List<AdCreateFeeRequestVO> fees = this.getFeesForVoucherType(adCreateRequestVO, accountDocumentInfo.getVoucherType());fee = new AdCreateFeeRequestVO();fee.setSupplierIdDetail(fees.get(0).getSupplierIdDetail());fee.setSupplierNameDetail(fees.get(0).getSupplierNameDetail());}//如果是关联交易,任意取一条if (adCreateRequestVO.isRelatedParty()) {List<AdCreateFeeRequestVO> fees = this.getFeesForVoucherType(adCreateRequestVO, accountDocumentInfo.getVoucherType());if (!CollectionUtils.isEmpty(fees)) {fee = fees.get(0);}}log.info("本次生成摘要===3");remark = this.buildAbstract(adCreateRequestVO, fee, abstrctRule);accountDocumentDetail = this.adAccountDocumentDetailService.populateDocumentDetail(subjectCode, dcFlag, adCreateRequestVO, amount, entrySeq++, accountDocumentInfo, remark);//借款核销单的供应商取行上第一条if (!Objects.isNull(fee)) {accountDocumentDetail.setFee(fee);accountDocumentDetail.setFeeJson(JSON.toJSONString(fee));}accountDocumentDetails.add(accountDocumentDetail);}return accountDocumentDetails;}

上面这个方法给人的第一感觉就是代码较多。首先,当一个方法的参数多于3个时最好用一个参数对象来封装这些入参;其次,方法的主体框架是由多个 if else 对于subjectCode进行判断构成,显然用状态模式来重构这个方法是再合适不过了。除了以上两个主要的优化点外,如果想做的更好话,还是有不少地方可以优化,比如其中调用的一个方法——getSubjectCodeByFee。

actualSubjectCode = adAccountRuleService.getSubjectCodeByFee(fee.getFeeItemsCode(), fee.getDeptType(), fee.getAssetFlag());

因为这个方法的入参全部来自于fee对象,所以完全可以将 getSubjectCodeByFee() 方法放入到fee类中,像下面这样,从而让“贫血”的Fee变成一个充血的Fee。

public class Fee {private String feeItemsCode;private String deptType;private Boolean isAsset;... 其他属性省略public String getSubjectCode() {Map<String, Object> param = new HashMap<>(2);param.put("feeItemCode", feeItemCode);if (isAsset()) {param.put("isAsset", isAsset);} else {param.put("deptType", deptType);}SpringUtil.getBean(XXDao.class).getSubjectCodeByFee(param);}
}

当然也可以这样。

    public String getSubjectCode(XXDao dao) {Map<String, Object> param = new HashMap<>(2);param.put("feeItemCode", feeItemCode);if (isAsset()) {param.put("isAsset", isAsset);} else {param.put("deptType", deptType);}dao.getSubjectCodeByFee(param);}

return Result还是 throw Exception,这是个问题

public class BillCommonLogic {...public Result checkContractAmtOccupy(Long billId) {Bill bill = billService.getOneById(billId);if (bill == null) {return Result.FAILURE.setMessage(ErrorMsgConstants.OBJECT_NOT_EXIST);}if (BillConstants.CONTRACT_AMT_OCCUPY_FAILED.equals(bill.getContractAmtOccupySuccess())) {return Result.FAILURE.setMessage(ErrorMsgConstants.NOT_ALLOW);}return Result.ok();}public Bill checkBillStatus(Long billId, String taskId) {Bill bill = billService.getOneById(billId);if (bill == null) {throw new BizException("单据不存在!");}if (bill.getBillStatus().equals(BillStateConstants.NOT_SUBMIT)) {logger.error(Constants.TASK_IS_REVOCATION);throw new BizException(Constants.TASK_IS_REVOCATION);}return bill;}...
}

重构之后

public class Bill {...private String billStatus;private String contractAmtOccupySuccess;...public void checkOccupationOfContractAmount() {BizAssert.isTrue(!BillConstants.CONTRACT_AMT_OCCUPY_FAILED.equals(contractAmtOccupySuccess), "合同金额占用失败");}public void checkStatusForProcess() {BizAssert.isTrue(!billStatus.equals(BillStatusConstants.NOT_SUBMIT), "单据已被撤回");}...
}

即使对BillCommonLogic中这两个方法进行了重构,但这两个方法在很多位置都有调用(差不多有一百多处),在一定程度上来说这也是一种代码重复。

如何简化这些调用,也就是最好只写一次Bill.checkStatusForProcess()便可替代的所有调用。是的,AOP是改动最小的方案。

先这样吧,等看到不爽的再来吐。

已经是公元2023年了,一定还有这么写代码的人儿。看看是如何把简单的事情搞复杂的。相关推荐

  1. 2023年湖北高考作文AI写

    本文由 大侠(AhcaoZhu)原创,转载请声明. 链接: https://blog.csdn.net/Ahcao2008 2023年湖北高考作文AI写

  2. 电脑微博批量删除-2023怎么批量删除微博网页版代码

    微博怎么快速批量删除_微博怎么把删除所有微博 你可以用它来批量删除微博.微博批量删除收藏和微博批量删除点赞内容,避免别人挖坟. 「2023批量删除微博工具」批量删除微博代码_手机暂时不能批量删除微博 ...

  3. 2023 最新微信域名拦截检测API代码

    2023最新微信域名拦截检测API源码,检测域名是否能在微信正常打开! 众所周知,域名在微信被封有3种情况: 第一种:浏览器访问 第二种:非官方网页 第三种:停止访问网页 被封原因: 第一种:腾讯垄断 ...

  4. 批量删微博丨2023简易版本控制台批量删除微博代码

    批量删微博丨简易版批量删除微博方法 微博点击头像到全是自己微博动态的个人主页 复制以下内容到浏览器控制台回车执行 function deleteMessage() {// 下箭头let iDom = ...

  5. CVPR 2023上46篇AIGC论文和代码

    刚刚过去的几个月,无疑是生成式AI爆发的奇点. 说到生成式AI,就不得不提到AIGC.AIGC全称为AI-Generated Content,指基于预训练大模型.生成式对抗网络(GAN)等人工智能技术 ...

  6. 2023编程必会的100个代码大全,建议立刻收藏

    前言 我记得刚开始接触编程的时候,觉得太难了.也很好奇,写代码的那些人也太厉害了吧?全是英文的,他们的英文水平一定很好吧?他们是怎么记住这么多代码格式的?而且错了一个标点符号,整个程序都会有影响.一个 ...

  7. 北邮信通2023大一下数据结构题目(含代码)

    这里写自定义目录标题 连续子序列最大和问题 题目 代码 1.复杂度O(n^3) 2.复杂度O(n^2) 3.复杂度O(n) 约瑟夫环问题 题目 代码 1.数组解法 4.分治原理 2.循环链表解法 连续 ...

  8. 2023最新USDT理财系统源码+代码完美流畅/框架二开/功能强大

    正文: 完整标题: 之前淘的一套PHP的理财源码,实测了下完美流畅,代码工整无错,UI简洁大方,有兴趣的朋友自己研究. 程序: wwegxs.lanzoux.com/ibfUk0l3c99a 图片:

  9. 2023 网站MySSL安全认证图标及代码

    代码可以在你的网站右下角有个认证图标. 只需要这串把代码放到 </body> 的上面就可以了(建议给个类名不要让样式冲突了)

最新文章

  1. 产品下级分类显示太宽了,请问在哪调整?
  2. SQL Server存储过程的基本概念以及语法【转】
  3. 【干货分享】如何应对线上数据库的误操作
  4. laravel框架安装(奶妈式手把手一步步操作)
  5. 500能不能配个玩英雄联盟的电脑?
  6. base定义了所有链接的URL
  7. java获取电脑配置_Java.Utils:获取电脑配置信息
  8. linux模拟发包工具,发包开源工具TRex在IPS测试中的应用
  9. 数字格式化输出NumberFormat
  10. java.exe 0xc000012d_应用程序无法正常启动0xc000012d,此情况要怎么解决,望大神交一交...
  11. 移动端与pc端的区别
  12. 常识:如何从大陆拨打国际长途电话到境外的方法
  13. python酒店数据分析_python数据分析实战——AirBnb用户分群
  14. CDH-TXKT-集群的维护
  15. Python做接口测试生成测试报告失败
  16. 电脑没有鼠标怎么打开计算机,电脑鼠标右键菜单没有打开方式选项怎么办
  17. pycharm安装教程-pycharm安装详细步骤(Mac版)
  18. 小程序集成Three.js,使用npm安装gsap动画库
  19. IE主页无法修改的办法
  20. python医疗影像_基于PyRadiomics的医疗影像纹理获取原型系统集成

热门文章

  1. [办公自动化]EXCEL不大,但是保存很慢
  2. C++实现等待一段时间
  3. 网上买书选三家,购物不要选当当
  4. ArduinoMEGA2560驱动AD7606模块 八路同步采样AD (16位并行数据传输)
  5. 上海人工智能核心企业突破1000家
  6. 使用盗版软件企业将入“黑名单” 降其信用等级
  7. ubuntu |DNS-response|: does not exist
  8. 2019最新C/C++游戏外挂编程项目实战(完整)
  9. 关于mysql存取图片的三种方式(含源码示例)
  10. 历年英语四级真题汇总(2015-2020)