buguge - Keep it simple,stupid

知识就是力量,但更重要的,是运用知识的能力why buguge?

导航

局部变量,在需要时再定义

关于局部变量,适时定义可以提高代码可读性并规避不必要的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;
}
View Code

 

 

是否依然有一种可能,你认为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;
}
View Code

 

 

局部变量,在需要时再定义,规避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));
}

 

 

 

 

posted on 2024-07-30 09:00  buguge  阅读(18)  评论(0编辑  收藏  举报