我是小懒猴,人狠话不多,直接上才艺。
简单的自述一下->模板设计模式,
在目前我的知识水平看来,模板设计模式是可以更好的改造业务执行流程。
主要分为两种
1、注解方式进行改造
2、抽象类兼接口进行改造
今天主要来讲解第二种方法抽象接口改造,如果新写业务接口,或者不同接口的功能,我们采用抽象接口配合执行器进行完成。
总步骤
- 执行器
- 抽象方法
- enum类
- 实现子类
- controller
第一步编写执行器
@Service
public class ApiBuilderExecute {
public <D,P> RespT<D> execute(String code, P param) {
return AbstractApiService.getService(code).execute(param);
}
}
这个就是执行器,当时写这个的时候,突发奇想,为什么要搞<D,P>这个东东,最后请教了两位同事,结合资料才明白,这个东西的重要性,我直接放下结论,我也不清楚是否表达正确,如若有误,看我顶置文章,加我联系方式,进行交流。
当一个方法的入参存在泛型的时候,是需要声明该方法为泛型方法,否则传参的时候会报出该类不能转化为T。
第二步编写抽象类
@Slf4j
@Component
public abstract class AbstractApiService<D,P> {
public static final HashMap<String,AbstractApiService> CACHE_MAP = new HashMap<>();
@PostConstruct
public void init() {
log.info("加载了当前service:{}",this.getClass().getSimpleName());
ApiEnum init = initApi();
if (null == init) {
log.error("Api服务初始化失败");
return;
}
CACHE_MAP.put(init.getCode(),this);
}
public abstract ApiEnum initApi();
/**
* 获取服务
*/
public static AbstractApiService getService(String code) {
if (StringUtils.isBlank(code)) {
throw new BusinessException(RespCodeEnum.REQUEST_ERROR);
}
AbstractApiService service = CACHE_MAP.get(code);
if (null == service) {
throw new BusinessException(RespCodeEnum.REQUEST_ERROR);
}
return service;
}
/**
* 执行业务
*
* @param reqVO 请求参数
* @return 执行结果
*/
public abstract RespT<D> execute(P reqVO);
}
抽象方法主要有两个,一个是ApiEnum,一个是execute执行业务方法,enum主要是为了获取你需要执行的Service子类,而execute主要是为了去执行该子类的方法。
init方法上的注解@PostConstruct,他会在第一次项目启动的时候进行加载,他会执行initApi方法,会加载所有实现该方法的类进行加载,初始化时将这些类放入到hashmap缓存当中。
第三步写枚举类
为了更好的统一管理,用枚举类进行约束
/**
* @Author: zcy_code
*/
@Getter
@AllArgsConstructor
public enum ApiEnum {
SELECT("select","查询"),
UPDATE("update","更新"),
;
String code;
String message;
private static final Map<String, ApiEnum> MAP = new HashMap<>();
static {
for (ApiEnum value : ApiEnum.values()) {
MAP.put(value.code, value);
}
}
/**
* 根据 Code 获取枚举对象
*
* @param code 枚举 Code
* @return 枚举对象
*/
public static ApiEnum get(String code) {
return MAP.get(code);
}
}
第四步写具体实现子类
@Slf4j
@Service
public class ApiSelectService extends AbstractApiService<ApiRespVo, ApiReqVo> {
@Override
public ApiEnum initApi() {
return ApiEnum.SELECT;
}
@Override
public RespT<ApiRespVo> execute(ApiReqVo reqVO) {
System.out.println("执行查询操作");
return new RespT<ApiRespVo>();
}
}
@Slf4j
@Service
public class ApiUpdateService extends AbstractApiService<ApiRespVo,ApiReqVo> {
@Override
public ApiEnum initApi() {
return ApiEnum.UPDATE;
}
@Override
public RespT<ApiRespVo> execute(ApiReqVo reqVO) {
System.out.println("进行更新操作");
return new RespT<ApiRespVo>();
}
}
该两个方法一个是查询操作,一个是更新操作,对只是两个简单操作,你会说,为什么写这么简单的方法,哈哈,你别犟。举个简单例子,假如在业务流程中,第一个为黑名单校验,第二个是企业天眼查校验 ,那是不是就完全不一样啦。到此是不是就基本完成了呢,大致是这样的,最后一步编写我们的controller方法。
第五步写Controller方法
@RestController
@RequestMapping("/api2/")
public class ApiController {
@Resource
ApiBuilderExecute apiBuilderExecute;
/**
* 查询操作
*/
@RequestMapping(path = "{code:select}")
public RespT select(@PathVariable String code, @RequestBody ApiReqVo reqVo) {
return apiBuilderExecute.execute(code,reqVo);
}
/**
* 查询操作
*/
@RequestMapping(path = "{code:update}")
public RespT update(@PathVariable String code, @RequestBody ApiReqVo reqVo) {
return apiBuilderExecute.execute(code,reqVo);
}
}