局部变量,在需要时再定义
关于局部变量,适时定义可以提高代码可读性并规避不必要的bug。示例代码中,为了避免误解`checkTaskApplyDTO`仅设置了`userId`,在`existAppliedTask`方法内部,可以通过将`checkTaskApplyDTO`的定义与设置属性的操作靠近,以明确其所有属性值的来源。另外,本文还展示了一个因提前定义变量`ret`而导致的bug实例。如果将此变量的定义延迟至其实际使用前,则可以避免此类问题。适时定义变量有助于减少混淆,提高代码质量。
关于局部变量,适时定义局部变量,可提高代码清晰度和可读性,并能规避不必要的代码bug
局部变量,在需要时再定义,提高代码可读性
下面代码中的2个方法,第1个 verifyTaskApply
调用第2个 existAppliedTask
。 请问,在 existAppliedTask
中调用 taskApplyService.getUserTaskApply
时, checkTaskApplyDTO 有哪些属性值?
private void verifyTaskApply(OrderDetailVO detail,List<UserSignVO> signedList) { log.info("收款人任务领取单校验,detailVO:{}", detail); if (detail == null || StringUtils.isBlank(detail.getUserIdcardNo()) || detail.getTaskId() == null || detail.getProviderId() == null || detail.getEnterpriseId() == null) { log.error("收款人任务领取单校验,参数错误,detailVO:{}", detail); throw new VerifyException(VerifyStatusResult.failedWithMessage("收款人任务领取单校验,参数错误")); } if (CollectionUtils.isEmpty(signedList)) { throw new VerifyException(VerifyStatusResult.failedWithMessage("签约记录未获取到")); } CheckTaskApplyDTO checkTaskApplyDTO = new CheckTaskApplyDTO(); checkTaskApplyDTO.setProviderId(detail.getProviderId()); checkTaskApplyDTO.setTaskId(detail.getTaskId()); checkTaskApplyDTO.setEnterpriseId(detail.getEnterpriseId()); checkTaskApplyDTO.setProductEnum(ProductEnum.BossKG); boolean exists = existAppliedTask(detail, checkTaskApplyDTO,signedList); if (!exists) { throw new VerifyException(VerifyStatusResult.failedWithMessage("收款人未领取任务")); } } private boolean existAppliedTask(OrderDetailVO detail, CheckTaskApplyDTO checkTaskApplyDTO, List<UserSignVO> signedList){ for (UserSignVO signVO : signedList) { detail.setUserId(signVO.getUserId()); detail.setUserSignBankCard(signVO.getUserBankCard()); checkTaskApplyDTO.setUserId(signVO.getUserId()); ResultX<TaskApplyVO> result = taskApplyService.getUserTaskApply(checkTaskApplyDTO); if (!result.isSuccess() || result.getResult() == null) { log.warn("收款人任务领取单校验,未领取任务,taskApplyQuery:{}", checkTaskApplyDTO); continue; } TaskApplyVO taskApplyVO = result.getResult(); detail.setTaskApplyId(taskApplyVO.getApplyId()); detail.setSignId(signVO.getSignId()); if (TaskApplyStatusEnum.TASKAPPLY_PASS == TaskApplyStatusEnum.getBean(taskApplyVO.getApplyStatus())) { return true; } log.warn("收款人任务领取单校验,收款人任务领取单未领取,taskApplyQuery:{}", checkTaskApplyDTO); } return false; }
有没有一种可能,你认为checkTaskApplyDTO只给了一个 userId属性值?
如果有,如何消除这种“可能的认为”呢?
so easy!下面隐藏的代码,告诉你答案。
private void verifyTaskApply(OrderDetailVO detail,List<UserSignVO> signedList) { ... boolean exists = existAppliedTask(detail, signedList); ... } private boolean existAppliedTask(OrderDetailVO detail, List<UserSignVO> signedList){ CheckTaskApplyDTO checkTaskApplyDTO = new CheckTaskApplyDTO(); checkTaskApplyDTO.setProviderId(detail.getProviderId()); checkTaskApplyDTO.setTaskId(detail.getTaskId()); checkTaskApplyDTO.setEnterpriseId(detail.getEnterpriseId()); checkTaskApplyDTO.setProductEnum(ProductEnum.BossKG); for (UserSignVO signVO : signedList) { detail.setUserId(signVO.getUserId()); detail.setUserSignBankCard(signVO.getUserBankCard()); checkTaskApplyDTO.setUserId(signVO.getUserId()); ResultX<TaskApplyVO> result = taskApplyService.getUserTaskApply(checkTaskApplyDTO); if (!result.isSuccess() || result.getResult() == null) { log.warn("收款人任务领取单校验,未领取任务,taskApplyQuery:{}", checkTaskApplyDTO); continue; } ... } return false; }
是否依然有一种可能,你认为checkTaskApplyDTO只给了一个 userId属性值?
如果有,如何消除这种“可能”呢?
so easy!下面隐藏的代码,告诉你答案。
private void verifyTaskApply(OrderDetailVO detail,List<UserSignVO> signedList) { ... } private boolean existAppliedTask(OrderDetailVO detail, List<UserSignVO> signedList){ for (UserSignVO signVO : signedList) { detail.setUserId(signVO.getUserId()); detail.setUserSignBankCard(signVO.getUserBankCard()); CheckTaskApplyDTO checkTaskApplyDTO = new CheckTaskApplyDTO(); checkTaskApplyDTO.setProviderId(detail.getProviderId()); checkTaskApplyDTO.setTaskId(detail.getTaskId()); checkTaskApplyDTO.setEnterpriseId(detail.getEnterpriseId()); checkTaskApplyDTO.setProductEnum(ProductEnum.BossKG); checkTaskApplyDTO.setUserId(signVO.getUserId()); ResultX<TaskApplyVO> result = taskApplyService.getUserTaskApply(checkTaskApplyDTO); if (!result.isSuccess() || result.getResult() == null) { log.warn("收款人任务领取单校验,未领取任务,taskApplyQuery:{}", checkTaskApplyDTO); continue; } ... } return false; }
局部变量,在需要时再定义,规避bug
下图,再一次证明 “变量在需要时再定义” 这个idea的正确性。
方法的开头定义了 ret 变量,从这个方法的逻辑,不难看出,这个 ret 是方法的返回值。 而在后面打印日志时,开发者不慎,误将 cardBinDTO 敲成了 ret ,显然,这是一个失误!
如果将 ret 变量的定义延后到 return 语句那块的话,就完全可以规避这个问题。
重要的事情说3遍:局部变量,在需要时再定义
再来看下面代码行,注意其中的 userDTO1。
User user = userManager.queryUserByMobile3FactorsCacheable(UserBO.convertUserDTO2UserFactorDTO(userDTO)); UserDTO userDTO1 = userDTOConverter.toDTO(user); if (userDTO1 == null) { saveUser(userDTO); userSaveNxDTO.setUserDTO(userDTO); log.info("用户新增,没有查询到数据,返回值:{}", JSON.toJSONString(userSaveNxDTO)); } else { userSaveNxDTO.setUserDTO(userDTO1); log.info("用户新增,获取到已经认证的数据,返回值:{}", JSON.toJSONString(userSaveNxDTO)); }
根据本文强调的主题”局部变量,在需要时再定义“,你有没有觉得 userDTO1 略显尴尬呢?
再者,这段代码中出现两个 UserDTO 对象,容易出现用错对象的情况。当同一个Class的多个对象出现在同一段代码内的时候,极易出错。
so,让我们做个小小的refactor。
User user = userManager.queryUserByMobile3FactorsCacheable(UserBO.convertUserDTO2UserFactorDTO(userDTO)); if (user == null) { saveUser(userDTO); userSaveNxDTO.setUserDTO(userDTO); log.info("用户新增,没有查询到数据,返回值:{}", JSON.toJSONString(userSaveNxDTO)); } else { userSaveNxDTO.setUserDTO(userDTOConverter.toDTO(user)); log.info("用户新增,获取到已经认证的数据,返回值:{}", JSON.toJSONString(userSaveNxDTO)); }
当看到一些不好的代码时,会发现我还算优秀;当看到优秀的代码时,也才意识到持续学习的重要!--buguge
本文来自博客园,转载请注明原文链接:https://www.cnblogs.com/buguge/p/18331073