基于模板方法+协调者委托对现有冗余代码的改造案例

一、背景

当前有一个应用服务,因为本次涉及到产品需求变更,当完成技术方案后,然后看了一下需要涉及变更的代码,发现有一个service及实现类,该实现类提供不同场景的三要素验证逻辑,总体验证逻辑就是先进行业务规则校验,如果检验不通过,则包装返回业务校验信息;如果校验通过,则进行数据库落库,存储当前身份认证信息。

但是基于当前产品需求,无非就是在service增加一个成员方法,然后实现类实现该方法,拷贝一下其他成员方法的业务逻辑,稍微改造一下,然后就实现了产品需求业务逻辑了。但是呢,看着当前这个service类,看到很多成员方法业务逻辑类似,不忍心将就一下,然后就想着怎么更好的思路重构一下现有的代码。

二、分析

我们先来看一下想要重构的代码原样

1、CustomerRelationService

接口代码

public interface CustomerRelationService {
    OpenIdRelation getBindedRelationByOpenId(String openId);
		/**
     * XXX绑定信息
     * @param dto
     * @return
     */
    RespDTO bindCustomer(BindOpenIdRequestDTO bindOpenIdRequestDTO);

    /**
     * XXX绑定信息
     * @param dto
     * @return
     */
    RespDTO releaseBindCustomer(BindOpenIdRequestDTO dto);
    /**
     * XXX绑定信息
     * @param dto
     * @return
     */
    RespDTO refundBindOpenId(BindOpenIdRequestDTO dto);

    List<OpenIdRelation> queryRecordsByIdno(String idno);
}

2、CustomerRelationServiceImpl

对应实现类:

@Service
@Slf4j
public class CustomerRelationServiceImpl implements CustomerRelationService {

    private static final String OPEN_ID = "openId";

    private static final String STATUS = "status";

    private static final int STATUS_BINDED = 0;

    static final int UPPER_LIMIT_ERROR_COUNT = 10;

    @Autowired
    private OpenIdRelationMapper openIdRelationMapper;

    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private MortgageService mortgageService;

    @Autowired
    MsgCacheManager msgCacheManager;

    @Autowired
    OrderCenterHttpApi orderCenterHttpApi;

    @Autowired
    MortgageHttpApi mortgageHttpApi;

    @Override
    public OpenIdRelation getBindedRelationByOpenId(String openId) {
        Map<String, Object> param = Maps.newHashMap();
        param.put(OPEN_ID, openId);
        param.put(STATUS, STATUS_BINDED);
        OpenIdRelation openIdRelation = openIdRelationMapper.selectByParam(param);
        return Optional.ofNullable(openIdRelation).orElse(null);
    }

    /**
     * XX绑定
     * @param verifyCode
     * @param mobile
     * @param idNo
     * @param realName
     * @param openId
     * @return
     */
    @Override
    public RespDTO bindCustomer(String verifyCode, String mobile, String idNo, String realName, String openId) {
        long totalCount = msgCacheManager.getRecordErrorCount(mobile);
        if(totalCount >= UPPER_LIMIT_ERROR_COUNT){
            return RespDTO.fail(String.format("短信验证码错误超过%s次,1分钟后再次重试!",totalCount));
        }
        String verifyCodeFromCache = msgCacheManager.getBindCacheValue(mobile);
        log.info("[绑定客户关系 从缓存中获取到到验证码为 verifyCode = {}]", verifyCodeFromCache);
        if (verifyCodeFromCache == null || !Objects.equals(verifyCodeFromCache, verifyCode)) {
            log.error("[绑定客户关系 验证码匹配失败 openId={}]", openId);
            msgCacheManager.recordErrorCount(mobile);
            return RespDTO.fail("短信验证码错误,请重新填写");
        }
        msgCacheManager.clearRecordErrorCount(mobile);
        List<MortgageDetailDTO> list = mortgageHttpApi.getMortgageDetailByIdNo(idNo);
        if (CollectionUtils.isEmpty(list)) {
            return RespDTO.fail("未查询到您的身份信息,请确认无误后重新提交");
        }
        MortgageDetailDTO mortgageDetailDTO = list.stream()
                .filter(mortgageDetail-> Objects.equals(mortgageDetail.getApiCustomerVO().getCustomerMobile(), mobile)
                        && Objects.equals(mortgageDetail.getApiCustomerVO().getCustomerName(), realName)).findFirst().orElse(null);
        if (ObjectUtils.isEmpty(mortgageDetailDTO)) {
            log.error("[绑定客户关系 提交信息与系统信息不匹配 openId = {}]", openId);
            return RespDTO.fail("未查询到您的身份信息,请确认无误后重新提交");
        }
        OpenIdRelation isExist = getBindedRelationByOpenId(openId);
        if (isExist != null) {
            log.error("[绑定客户关系 用户信息已绑定 openId = {}]", openId);
            return RespDTO.success();
        }

        Customer customer = Customer.builder().idno(idNo).realName(realName).mobile(mobile).build();
        long insertCount = customerMapper.insertSelective(customer);
        if (insertCount != 0) {
            OpenIdRelation openIdRelation = OpenIdRelation.builder().customerId(customer.getId()).openId(openId).idNo(idNo).status(OpenIdRelation.BIND_STATUS)
                    .bindTime(new Date()).build();
            openIdRelationMapper.insertSelective(openIdRelation);
        }

        return RespDTO.success();
    }


    /**
     * 校验验证码,错误则返回
     * @return
     */
    private RespDTO verifyCode(BindOpenIdRequestDTO dto){
        String cacheValue = msgCacheManager.getBindCacheValue(dto.getMobile());
        return VerifyCodeUtil.verify(cacheValue, dto.getOpenId(), dto.getVerifyCode());
    }

    /**
     * XX绑定信息
     * @param dto
     * @return
     */
    @Override
    public RespDTO releaseBindCustomer(BindOpenIdRequestDTO dto) {
        //1、校验验证码,错误则返回
        RespDTO resp = verifyCode(dto);
        if (RespStatusEnum.FAIL.getStatus() == resp.getStatus()){
            return resp;
        }

        //2、从订单中心查询客户信息是否匹配,不存在则返回
        String idNo = dto.getIdNo();
        String openId = dto.getOpenId();
        List<OrderDetailVO> list = orderCenterHttpApi.queryOrderInfoByIdNo(idNo);
        OrderDetailVO detailVO = list.stream().filter(o -> Objects.nonNull(o.getApplicantDetailVO())
                && Objects.equals(dto.getRealName(), o.getApplicantDetailVO().getName())
                && (Objects.equals(dto.getMobile(), o.getApplicantDetailVO().getMobile())
                    || Objects.equals(dto.getMobile(), o.getApplicantDetailVO().getMobile2()))).findAny().orElse(null);
        if (Objects.isNull(detailVO)){
            log.error("[XXXXX 提交信息与系统信息不匹配 openId = {}]", openId);
            return RespDTO.fail("未查询到您的身份信息,请确认无误后重新提交");
        }

        //3、判断是否已经绑定,绑定则返回
        if (null != getBindedRelationByOpenId(openId)) {
            log.error("[XXXXX 用户信息已绑定 openId = {}]", openId);
            return RespDTO.success();
        }

        //4、未绑定,则进行绑定
        bind(dto);
        return RespDTO.success();
    }

    /**
     * XXX绑定
     * @param dto
     * @return
     */
    @Override
    public RespDTO refundBindOpenId(BindOpenIdRequestDTO dto) {
        //1、校验验证码,错误则返回
        RespDTO respDTO = verifyCode(dto);
        if (RespStatusEnum.FAIL.getStatus() == respDTO.getStatus()){
            return respDTO;
        }

        //2、从订单中心查询客户信息是否匹配,不存在则返回
        String openId = dto.getOpenId();
        RespDTO<TransferRefundOrderRe> resp = mortgageHttpApi.queryRefundOrder(dto.getIdNo());
        TransferRefundOrderRe refundVO = resp.getData();
        if (Objects.isNull(refundVO)){
            log.error("[退款绑定客户关系 提交信息与系统信息不匹配 openId = {}]", openId);
            return RespDTO.fail("未查询到您的身份信息,请确认无误后重新提交");
        }

        //3、判断是否已经绑定,绑定则返回
        if (null != getBindedRelationByOpenId(openId)) {
            log.error("[退款绑定客户关系 用户信息已绑定 openId = {}]", openId);
            return RespDTO.success();
        }

        //4、未绑定,则进行绑定
        bind(dto);
        return RespDTO.success();
    }

    @Override
    public List<OpenIdRelation> queryRecordsByIdno(String idno) {
        List<OpenIdRelation> list = openIdRelationMapper.queryRecordsByIdno(idno);
        return list;
    }

    /**
     * 保存绑定数据
     * @param dto
     */
    private void bind(BindOpenIdRequestDTO dto){
        Customer customer = Customer.builder().idno(dto.getIdNo()).realName(dto.getRealName()).mobile(dto.getMobile()).build();
        long insertCount = customerMapper.insertSelective(customer);
        if (insertCount != 0) {
            openIdRelationMapper.insertSelective(
                    OpenIdRelation.builder()
                            .customerId(customer.getId()).openId(dto.getOpenId()).idNo(dto.getIdNo())
                            .status(OpenIdRelation.BIND_STATUS).bindTime(new Date()).build()
            );
        }
    }
}

上述类有三个重要的方法如下,上面实现类就是基于下面三种方法的不同场景的业务逻辑实现

RespDTO bindCustomer(BindOpenIdRequestDTO bindOpenIdRequestDTO);

/**
 * @param dto
 * @return
 */
RespDTO releaseBindCustomer(BindOpenIdRequestDTO dto);
/**
 * @param dto
 * @return
 */
RespDTO refundBindOpenId(BindOpenIdRequestDTO dto);

总体而言,重构的思路就是通过模板方法定义一个抽象类,然后三个不同的方法就是抽象类的三个不同实现类,相同的代码逻辑(即前置业务校验+绑定)则抽象在抽象类中,对外暴露一个公共方法。

然后通过一个委托代理类,通过上线文对象来封装不同的业务场景类型,然后委托对应的抽象类的实现类来处理业务逻辑,这样以来,如果再增加绑定方法时,只需要增加相应的子类,同事修改某个场景时,也只需要修改对应的子类即可,这样符合开闭原则。

三、重构

1、UML设计

在这里插入图片描述

整体设计思路

  • 通过定义抽象类AbstractBindHandler,把相关三要素场景校验的步骤封装起来,对于子类只需要实现前置校验抽象方法即可。
  • 通过定义BindContext上下文对象,封装整个流程所依赖的请求参数和输出。
  • 通过定义枚举类Biz,然后实现增加响应的Handler,只需要在枚举类增加成员即可。
  • 通过定义BindHandlerDispatcher,实现对Handler的封装,对于外部业务调用只需要跟BindHandlerDispatcher交互即可,屏蔽Handler类的细节。
  • 后续如果增加业务场景,只需要增加Handler类即可,如果修改对应业务场景,只需要找到对应Handler类修改即可,即符合开闭原则。

2、BindContext

该类包含三个常用属性,param输出参数,Handler类所依赖的参数通过param传输,该类型是个泛型,需要Handler类来定义声明,Biz是个枚举类。

/**
 * @description: 客户绑定上下文对象
 * @Date : 2021/10/29 5:52 PM
 * @Author : 石冬冬-Seig Heil
 */
@Data
@Builder
public class BindContext<P> {
    /**
     * DTO参数
     */
    private P param;
    /**
     * 业务类型
     */
    private Biz biz;
    /**
     * 响应报文
     */
    private RespDTO respDTO;

    /**
     * 业务类型
     */
    public enum Biz{
        /**
         * XXX付款客户绑定
         */
        ESC_PAYMENT_BIND,
        /**
         * XXX退款客户绑定
         */
        ESC_REFUND_BIND,
        /**
         * XXX解押客户绑定
         */
        ESC_RELEASE_BIND,
        /**
         * XXX解押客户绑定
         */
        CRZ_RELEASE_BIND
    }
}

3、AbstractBindHandler

Handler类的基类,依然是个泛型抽象类,需要子类来声明输入参数Param需要继承BindOpenIdRequestDTO。

/**
 * @description: 抽象公众号客户三要素绑定处理器
 * @Date : 2021/10/29 5:51 PM
 * @Author : 石冬冬-Seig Heil
 */
public abstract class AbstractBindHandler<P extends BindOpenIdRequestDTO> {
    /**
     * 进行绑定的标识
     */
    final String BIND_TAG = "BIND";

    @Autowired
    DiamondConfigProxy diamondConfigProxy;

    @Autowired
    OpenIdRelationMapper openIdRelationMapper;

    @Autowired
    CustomerMapper customerMapper;

    @Resource
    CustomerRelationService customerRelationService;

    @Autowired
    MortgageService mortgageService;

    @Autowired
    MsgCacheManager msgCacheManager;

    @Autowired
    OrderCenterHttpApi orderCenterHttpApi;

    @Autowired
    MortgageHttpApi mortgageHttpApi;
    /**
     * 前置校验
     * @param context 上下文
     * @return
     */
    abstract RespDTO verify(BindContext<P> context);

    /**
     * 对外暴露方法
     * @param context
     */
    public void handle(BindContext<P> context){
        RespDTO respDTO = verify(context);
        context.setRespDTO(respDTO);
        boolean canBind = respDTO.getStatus() ==  RespStatusEnum.SUCCESS.getStatus() && BIND_TAG.equals(respDTO.getData());
        if(canBind){
            bind(context.getParam());
            context.setRespDTO(RespDTO.success());
        }
    }


    /**
     * 保存绑定数据
     * @param dto
     */
    private void bind(BindOpenIdRequestDTO dto){
        Customer customer = Customer.builder().idno(dto.getIdNo()).realName(dto.getRealName()).mobile(dto.getMobile()).build();
        long insertCount = customerMapper.insertSelective(customer);
        if (insertCount != 0) {
            openIdRelationMapper.insertSelective(
                    OpenIdRelation.builder()
                            .customerId(customer.getId()).openId(dto.getOpenId()).idNo(dto.getIdNo())
                            .status(OpenIdRelation.BIND_STATUS).bindTime(new Date()).build()
            );
        }
    }

    /**
     * 根据openId查询已经绑定的关系
     * @param openId
     * @return
     */
    protected OpenIdRelation getBindedRelationByOpenId(String openId) {
        return customerRelationService.getBindedRelationByOpenId(openId);
    }

    /**
     * 校验验证码,错误则返回
     * @return
     */
    RespDTO verifyCode(BindOpenIdRequestDTO dto){
        String cacheValue = msgCacheManager.getBindCacheValue(dto.getMobile());
        return VerifyCodeUtil.verify(cacheValue, dto.getOpenId(), dto.getVerifyCode());
    }
}

相关实现类

CrzReleaseBindHandler
@Service
@Slf4j
public class CrzReleaseBindHandler extends AbstractBindHandler<BindOpenIdRequestDTO>{

    @Autowired
    MortgageHttpApi mortgageHttpApi;

    @Override
    RespDTO verify(BindContext<BindOpenIdRequestDTO> context) {
        BindOpenIdRequestDTO dto = context.getParam();
        //1、校验验证码,错误则返回
        RespDTO respDTO = verifyCode(dto);
        if (RespStatusEnum.FAIL.getStatus() == respDTO.getStatus()){
            return respDTO;
        }
        MockConfig mockConfig = diamondConfigProxy.mockConfig();
        List<String> idnoMockList = mockConfig.getReleaseIdNoMockList();
        //身份证白名单 忽略三要素验证
        boolean whiteIdno = null != idnoMockList && idnoMockList.contains(dto.getIdNo());
        if(!whiteIdno){
            //2、身份校验
            CrzReleaseBindVerifyDTO bindVerifyDTO = CrzReleaseBindVerifyDTO.builder()
                    .customerIdno(dto.getIdNo()).customerMobile(dto.getMobile()).customerName(dto.getRealName())
                    .build();
            try {
                RespDTO<String> bindResult = mortgageHttpApi.bindVerify(bindVerifyDTO);
            } catch (InvokeException e) {
                log.error("[CrzReleaseBindHandler#verify]",e);
                return RespDTO.fail(e.getErrMsg());
            }
        }
        //2、判断是否已经绑定,绑定则返回
        String openId = dto.getOpenId();
        if (null != getBindedRelationByOpenId(openId)) {
            log.error("[退款绑定客户关系 用户信息已绑定 openId = {}]", openId);
            return RespDTO.success();
        }
        return RespDTO.success(BIND_TAG);
    }
}
EscPaymentBindHandler
/**
 * @description: 二手车付款 客户绑定 处理器
 * @Date : 2021/10/29 6:01 PM
 * @Author : 石冬冬-Seig Heil
 */
@Service
@Slf4j
public class EscPaymentBindHandler extends AbstractBindHandler<BindOpenIdRequestDTO>{
    /**
     * 短信验证码错误次数阈值上限
     */
    final int UPPER_LIMIT_ERROR_COUNT = 10;

    @Override
    RespDTO verify(BindContext<BindOpenIdRequestDTO> context) {
        BindOpenIdRequestDTO dto = context.getParam();
        String verifyCode = dto.getVerifyCode(), mobile = dto.getMobile(), idNo = dto.getIdNo(), realName = dto.getRealName(), openId = dto.getOpenId();
        long totalCount = msgCacheManager.getRecordErrorCount(mobile);
        if(totalCount >= UPPER_LIMIT_ERROR_COUNT){
            return RespDTO.fail(String.format("短信验证码错误超过%s次,1分钟后再次重试!",totalCount));
        }
        String verifyCodeFromCache = msgCacheManager.getBindCacheValue(mobile);
        log.info("[绑定客户关系 从缓存中获取到到验证码为 verifyCode = {}]", verifyCodeFromCache);
        if (verifyCodeFromCache == null || !Objects.equals(verifyCodeFromCache, verifyCode)) {
            log.error("[绑定客户关系 验证码匹配失败 openId={}]", openId);
            msgCacheManager.recordErrorCount(mobile);
            return RespDTO.fail("短信验证码错误,请重新填写");
        }
        msgCacheManager.clearRecordErrorCount(mobile);
        List<MortgageDetailDTO> list = mortgageHttpApi.getMortgageDetailByIdNo(idNo);
        if (CollectionUtils.isEmpty(list)) {
            return RespDTO.fail("未查询到您的身份信息,请确认无误后重新提交");
        }
        MortgageDetailDTO mortgageDetailDTO = list.stream()
                .filter(mortgageDetail-> Objects.equals(mortgageDetail.getApiCustomerVO().getCustomerMobile(), mobile)
                        && Objects.equals(mortgageDetail.getApiCustomerVO().getCustomerName(), realName)).findFirst().orElse(null);
        if (ObjectUtils.isEmpty(mortgageDetailDTO)) {
            log.error("[绑定客户关系 提交信息与系统信息不匹配 openId = {}]", openId);
            return RespDTO.fail("未查询到您的身份信息,请确认无误后重新提交");
        }
        OpenIdRelation isExist = getBindedRelationByOpenId(openId);
        if (isExist != null) {
            log.error("[绑定客户关系 用户信息已绑定 openId = {}]", openId);
            return RespDTO.success();
        }

        Customer customer = Customer.builder().idno(idNo).realName(realName).mobile(mobile).build();
        long insertCount = customerMapper.insertSelective(customer);
        if (insertCount != 0) {
            OpenIdRelation openIdRelation = OpenIdRelation.builder().customerId(customer.getId()).openId(openId).idNo(idNo).status(OpenIdRelation.BIND_STATUS)
                    .bindTime(new Date()).build();
            openIdRelationMapper.insertSelective(openIdRelation);
        }

        return RespDTO.success(BIND_TAG);
    }
}
EscRefundBindHandler
/**
 * @description: 二手车退款客户绑定 处理器
 * @Date : 2021/10/29 6:01 PM
 * @Author : 石冬冬-Seig Heil
 */
@Service
@Slf4j
public class EscRefundBindHandler extends AbstractBindHandler<BindOpenIdRequestDTO>{

    @Override
    RespDTO verify(BindContext<BindOpenIdRequestDTO> context) {
        BindOpenIdRequestDTO dto = context.getParam();
        //1、校验验证码,错误则返回
        RespDTO respDTO = verifyCode(dto);
        if (RespStatusEnum.FAIL.getStatus() == respDTO.getStatus()){
            return respDTO;
        }

        //2、从订单中心查询客户信息是否匹配,不存在则返回
        String openId = dto.getOpenId();
        RespDTO<TransferRefundOrderRe> resp = mortgageHttpApi.queryRefundOrder(dto.getIdNo());
        TransferRefundOrderRe refundVO = resp.getData();
        if (Objects.isNull(refundVO)){
            log.error("[退款绑定客户关系 提交信息与系统信息不匹配 openId = {}]", openId);
            return RespDTO.fail("未查询到您的身份信息,请确认无误后重新提交");
        }

        //3、判断是否已经绑定,绑定则返回
        if (null != getBindedRelationByOpenId(openId)) {
            log.error("[退款绑定客户关系 用户信息已绑定 openId = {}]", openId);
            return RespDTO.success();
        }
        return RespDTO.success(BIND_TAG);
    }
}
EscReleaseBindHandler
/**
 * @description: 二手车解押客户绑定 处理器
 * @Date : 2021/10/29 6:01 PM
 * @Author : 石冬冬-Seig Heil
 */
@Service
@Slf4j
public class EscReleaseBindHandler extends AbstractBindHandler<BindOpenIdRequestDTO>{

    @Override
    RespDTO verify(BindContext<BindOpenIdRequestDTO> context) {
        BindOpenIdRequestDTO dto = context.getParam();
        //1、校验验证码,错误则返回
        RespDTO resp = verifyCode(dto);
        if (RespStatusEnum.FAIL.getStatus() == resp.getStatus()){
            return resp;
        }

        //2、从订单中心查询客户信息是否匹配,不存在则返回
        String idNo = dto.getIdNo();
        String openId = dto.getOpenId();
        List<OrderDetailVO> list = orderCenterHttpApi.queryOrderInfoByIdNo(idNo);
        OrderDetailVO detailVO = list.stream().filter(o -> Objects.nonNull(o.getApplicantDetailVO())
                && Objects.equals(dto.getRealName(), o.getApplicantDetailVO().getName())
                && (Objects.equals(dto.getMobile(), o.getApplicantDetailVO().getMobile())
                || Objects.equals(dto.getMobile(), o.getApplicantDetailVO().getMobile2()))).findAny().orElse(null);
        if (Objects.isNull(detailVO)){
            log.error("[解押绑定客户关系 提交信息与系统信息不匹配 openId = {}]", openId);
            return RespDTO.fail("未查询到您的身份信息,请确认无误后重新提交");
        }

        //3、判断是否已经绑定,绑定则返回
        if (null != getBindedRelationByOpenId(openId)) {
            log.error("[解押绑定客户关系 用户信息已绑定 openId = {}]", openId);
            return RespDTO.success();
        }
        return RespDTO.success(BIND_TAG);
    }
}

4、BindHandlerDispatcher

该类的职责相当于Handler的协调者,它根据context的类型biz,进而指挥对应的Handler类

/**
 * @description: 客户关系绑定处理分发器
 * @Date : 2021/10/29 6:19 PM
 * @Author : 石冬冬-Seig Heil
 */
@Component
public class BindHandlerDispatcher {

    @Resource
    EscPaymentBindHandler escPaymentBindHandler;

    @Resource
    EscReleaseBindHandler escReleaseBindHandler;

    @Resource
    EscRefundBindHandler escRefundBindHandler;

    @Resource
    CrzReleaseBindHandler crzReleaseBindHandler;

    /**
     * 根据业务类型分发对应的处理器来处理
     * @param context
     */
    public void dispatch(BindContext context){
        switch (context.getBiz()){
            case ESC_PAYMENT_BIND:
                escPaymentBindHandler.handle(context);
                return;
            case ESC_REFUND_BIND:
                escRefundBindHandler.handle(context);
                return;
            case ESC_RELEASE_BIND:
                escReleaseBindHandler.handle(context);
                return;
            case CRZ_RELEASE_BIND:
                crzReleaseBindHandler.handle(context);
                return;
        }
    }
}

5、CustomerRelationServiceImpl

重构后,这里的成员方法只需要构造BindContext实例对象,然后调用Dispatcher.dispatch的成员方法即可,代码这时候看起来清爽许多。

/**
 * XX绑定
 * @param dto
 * @return
 */
@Override
public RespDTO bindCustomer(BindOpenIdRequestDTO dto) {
    BindContext<BindOpenIdRequestDTO> context = BindContext.<BindOpenIdRequestDTO>builder().biz(BindContext.Biz.ESC_PAYMENT_BIND).param(dto).build();
    bindHandlerDispatcher.dispatch(context);
    return context.getRespDTO();
}

/**
 * XX绑定信息
 * @param dto
 * @return
 */
@Override
public RespDTO releaseBindCustomer(BindOpenIdRequestDTO dto) {
    BindContext<BindOpenIdRequestDTO> context = BindContext.<BindOpenIdRequestDTO>builder().biz(BindContext.Biz.ESC_RELEASE_BIND).param(dto).build();
    bindHandlerDispatcher.dispatch(context);
    return context.getRespDTO();
}

/**
 * XX绑定
 * @param dto
 * @return
 */
@Override
public RespDTO releaseBindCustomerForCrz(BindOpenIdRequestDTO dto) {
    BindContext<BindOpenIdRequestDTO> context = BindContext.<BindOpenIdRequestDTO>builder().biz(BindContext.Biz.CRZ_RELEASE_BIND).param(dto).build();
    bindHandlerDispatcher.dispatch(context);
    return context.getRespDTO();
}

/**
 * XX绑定
 * @param dto
 * @return
 */
@Override
public RespDTO refundBindOpenId(BindOpenIdRequestDTO dto) {
    BindContext<BindOpenIdRequestDTO> context = BindContext.<BindOpenIdRequestDTO>builder().biz(BindContext.Biz.ESC_REFUND_BIND).param(dto).build();
    bindHandlerDispatcher.dispatch(context);
    return context.getRespDTO();
}

四、总结

通过重构前后对比,我们发现整个Service类(CustomerRelationServiceImpl)的的代码这时候通过Handler类来封装了,而service类中仅仅只需要委托Dispatcher整个类,通过构造BindContext实例对象,进而调用其dispatch方法即可。

整个service对外提供的方法并没有做任何改变,后续如果增加成员方法,只需要增加Handler类即可。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值