Java Service实现类中处理复杂逻辑的一种写法

编写步骤:

1. 定义一个通用的业务接口

public interface SingleOperation<R> {

    RestResponse<R> doOperation();
}

2. 在Service实现类中定义一个复杂业务处理包装子类比如:创建付款单业务【CreatePayment】去实现SingleOperation接口

/**
 * 创建付款单业务
 */
private class CreatePayment implements SingleOperation<String> {
    final org.slf4j.Logger log = CREATE_LOG;
    final FundPaymentCreateRequest request;
    FundPayment newPayment;

    private CreatePayment(final FundPaymentCreateRequest request) {
        this.request = request;
    }

    @Override
    public RestResponse<String> doOperation() {
        // 1. 检查必要参数
        // 2. 没有单号则生成单号(调用方要保证不要重复请求)
        // 3. 插数据
        // 4. 发消息

        // 1. 检查基本参数
        final ParamValidationResult checkResult = checkCreateParam(request);
        if (!checkResult.isPass()) {
            return checkResult.toRestResponse();
        }

        // 2 若没有单号,生成一个单号
        final String paymentNo;
        final boolean paymentNoExists;
        {
            final String existsPaymentNo = request.getPaymentNo();
            if (!StringUtils.isEmpty(existsPaymentNo)) {
                // 外面传了单号进来,直接使用,并且需要校验此单号对应的付款单是否存在
                paymentNo = existsPaymentNo;
                paymentNoExists = true;
            } else {
                // 没有单号,生成一个,并且后面不需要验证了
                paymentNo = ascIdGenerator.generateString(FUND_PAYMENT);
                paymentNoExists = false;
            }
        }

        // 决定一下初始的 paymentStatus 是啥 ,传了则以传的为准,不传则默认
        final EnumFundPaymentStatus paymentStatus =       Optional.ofNullable(request.getPaymentStatus()).orElse(EnumFundPaymentStatus.TO_AUDIT);
        // 决定线上线下类型,传了以传的为准,不传则 receiverAccount 为空线下,不为空线上
        final EnumFundPaymentType paymentType = Optional.ofNullable(request.getPaymentType()).orElseGet(() -> {
            if (StringUtils.isEmpty(request.getReceiverAccount())) {
                return EnumFundPaymentType.OFFLINE;
            } else {
                return EnumFundPaymentType.ONLINE;
            }
        });


        // 3. 准备插入数据
        return transactionTemplate.execute(status -> {
            // 如果单号是传进来的,先校验一遍是否存在
            if (paymentNoExists) {
                final FundPayment queryEntity = new FundPayment();
                queryEntity.setPaymentNo(paymentNo);
                final Integer count = fundPaymentMapper.selectCount(new QueryWrapper<>(queryEntity));
                if (count > 0) {
                    log.warn("创建付款单失败,付款单号 [{}] 重复。请求:[{}]", paymentNo, request);
                    return fail(EnumCommonRestResponseCode.BusinessError, "付款单号重复,不能创建");
                }
            }

            // 可以新增了
            newPayment = new FundPayment();
            newPayment.setPaymentNo(paymentNo);
            newPayment.setAmount(request.getAmount());
            newPayment.setPaymentStatus(paymentStatus);
            newPayment.setPaymentType(paymentType);
            newPayment.setPayAccount(request.getPayAccount());
            newPayment.setPayName(request.getPayName());
            newPayment.setReceiverAccount(request.getReceiverAccount());
            newPayment.setReceiverName(request.getReceiverName());
            newPayment.setRemark(request.getRemark());
            fundPaymentMapper.insert(newPayment);

            // 新增关系
            final List<FundPaymentRelation> entities = request.getRelationList().stream().map(v -> {
                final FundPaymentRelation entity = new FundPaymentRelation();
                entity.setPaymentNo(paymentNo);
                entity.setRelationType(v.getRelationType());
                entity.setRelationNo(v.getRelationNo());
                entity.fillInsert();
                return entity;
            }).collect(Collectors.toList());
            if (entities != null && entities.size() > 0) {
                fundPaymentRelationMapper.batchInsert(entities);
            }

            // 发消息
            sendMq();
            return success(paymentNo);
        });
    }

这样我们把一个复杂的业务拆分成多个子类,去写各自的逻辑,就可以把复杂问题简单化,而不是我们通过抽取方法,方法之间互相调用,这样业务复杂了,代码很难读懂。

猜你喜欢

转载自blog.csdn.net/weixin_39352976/article/details/104872831
今日推荐