转至元数据结尾
转至元数据起始

局部变量,在需要时再定义,提高代码可读性

下面代码中的2个方法,第1个 verifyTaskApply 调用第2个 existAppliedTask。 请问,在 existAppliedTask 中调用 taskApplyService.getUserTaskApply(checkTaskApplyDTO); 时, 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());
//            detail.setWorkTypeName(taskApplyVO.getWorkTypeName());

        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

下图,再一次证明 “变量在需要时再定义” 这句话的正确性。

方法的开头定义了 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 对象,容易出现用错对象的情况。

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));
    }




编写评论...