相同结构不同业务的模版方法抽象

背景介绍:

A服务是基础服务,靠一个appid做省份的隔离,这个appid需要调用方设置请求头传入,一般情况是前端请求,用户的数据自然可以得知省份;
B服务做统计的业务,需要从A服务读取数据。这个调用完全是后端之间的服务调用,所以需要自己设置appid的请求头。同时旧的结构是没做省份隔离的,所以需要读所有省份的数据合并返回与旧的返回结果结构相同,才能兼容旧的代码。

实现

一开始想用代理模式,不过这样会需要改动原来的业务代码,又想到每个请求的结构类似,所以抽象出如下的代码:

  1. 把appid设置在配置文件里面
  2. 模版
@Slf4j
public abstract class AbstractItemsUomClientTemplate {

    public abstract void checkParam();

    public abstract T call();

    public abstract String getErrorMsgTitle();

    public final T execute(List appIdList) {
        if(CollectionUtils.isEmpty(appIdList)) {
            return null;
        }
        checkParam();

        List voList = new ArrayList<>();
        appIdList.stream().forEach(appId -> {
            try {
                XXXXXContext.setSdpAppId(appId);
                T vo = call();
                if (vo != null && CollectionUtils.isNotEmpty(vo.getItems())) {
                    voList.add(vo);
                }
            } catch (Exception e) {
                log.error(getErrorMsgTitle(),e);
            }
        });
        if(CollectionUtils.isEmpty(voList)) {
            return null;
        }
         //  把每个省份的数据合并
        return (T) merge(voList);
    }
}
  1. 使用:
    把请求头的部分提取出来,下次再写的时候,只需要关注业务调用,省份的隔离变得无感知了
public XXX  getXXXXXByXXXX(......) {

        // ...
        XXX xxx = new AbstractItemsUomClientTemplate() {
            @Override
            public void checkParam() {
                //  校验
            }

            @Override
            public XXX call() {
                // 在这里调用A服务
            }

            @Override
            public String getErrorMsgTitle() {
                return "....";
            }
        }.execute(appIdConfig.getList());

        return xxx;
    }

总结

适用于结构类似的方法,抽象出来,方便维护和扩展

你可能感兴趣的:(相同结构不同业务的模版方法抽象)