当前公司项目有旧项目需要改造,看了下以前的代码,部分逻辑if else太多,因此使用工厂模式解耦。
1、首先定义业务的类型,按类型区分,这里采用了枚举方式定义:
@Getter
public enum RequestCategoryEnum {
OPERATION_REQUEST(10, "动作指令", "operationRequestService"),
COMPOSITE_REQUEST(20, "组合指令", "compositeRequestService"),
GOAL_REQUEST(30, "目标指令", "goalRequestService"),
QUERY_REQUEST(40, "查询指令", "queryRequestService"),;
/**
* id
*/
private Integer id;
/**
* 实现类
*/
private String implementClassName;
/**
* 名称
*/
private String name;
RequestCategoryEnum(Integer id, String name, String implementClassName) {
this.id = id;
this.name = name;
this.implementClassName = implementClassName;
}
public static RequestCategoryEnum getById(Integer id) {
for (RequestCategoryEnum it : RequestCategoryEnum.values()) {
if (it.id.equals(id)) {
return it;
}
}
return null;
}
}
2、定义注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface RequestCategoryHandler {
RequestCategoryEnum value();
}
3、初始化注解服务
/**
* 策略核心功能,获取所有策略注解的类型
* 并将对应的class初始化到HandlerRequestTypeContext中
* @author zhenghui
* @date 2019-11-20
*/
@Component
public class HandlerRequestCategoryProcessor implements ApplicationContextAware {
/**
* 获取所有的策略加入HandlerRequestCategoryFactory属性中
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//获取所有策略注解的Bean
Map<String, Object> requestStrategyMap = applicationContext.getBeansWithAnnotation(RequestCategoryHandler.class);
requestStrategyMap.forEach((k,v)->{
RequestCategoryHandler handler = AnnotationUtils.findAnnotation(v.getClass(), RequestCategoryHandler.class);
RequestCategoryEnum type = handler.value();
//加入map中,type作为key
HandlerRequestCategoryFactory.putStrategy(type.getId(), (IRequestCategoryStrategy) v);
});
}
}
4、构建工厂类,提供给外部使用
@Component
public class HandlerRequestCategoryFactory {
//存放所有策略类的map
public static Map<Integer, IRequestCategoryStrategy> requestCategoryStrategyMap = new HashMap<>();
public static void putStrategy(Integer id, IRequestCategoryStrategy strategy){
requestCategoryStrategyMap.put(id, strategy);
}
public IRequestCategoryStrategy getStrategyByRequest(Integer type){
IRequestCategoryStrategy requestStrategy = requestCategoryStrategyMap.get(type);
if(requestStrategy == null){
throw new IllegalArgumentException(String.format("没有对应的指令[%d]", type));
}
//获取对应的策略
return requestStrategy;
}
}
5、构建接口类
public interface IRequestCategoryStrategy {
ExecuteResult<List<RequestTask>> parseRequestTask(Request request);
}
6、实现接口类
@Slf4j
@Service("goalRequestService")
@RequestCategoryHandler(RequestCategoryEnum.GOAL_REQUEST)
public class GoalRequestCategoryService extends IRequestCategoryStrategy {
/**
* 动作计划
*/
@Autowired
private OperationPlanningService operationPlanningService;
/**
* 解析任务
*
* @param request
* @return
*/
@Override
protected ExecuteResult<List<RequestTask>> parseRequestTask(Request request) {
return this.resolve(request);
}
/**
* 分解指令
*
* @param request
* @return
*/
private ExecuteResult<List<RequestTask>> resolve(Request request) {
ExecuteResult<List<RequestTask>> result = operationPlanningService.resolve(request);
if (result.getSuccess()) {
return result;
}
return ExecuteResult.fail(result.getMessage());
}
}
7、在业务调用位置定义factory
@Autowired
private HandlerRequestCategoryFactory requestCategoryFactory;
//找到对应指令类型的处理服务
IRequestCategoryStrategy requestCategoryStrategy =
requestCategoryFactory.getStrategyByRequest(request.getRequestCategory());
requestCategoryStrategy.execute(request);