阅读 165

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

一、背景

当前有一个应用服务,因为本次涉及到产品需求变更,当完成技术方案后,然后看了一下需要涉及变更的代码,发现有一个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类即可。


作者:秋夜无霜
链接:https://juejin.cn/post/7029582156309463048


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐