本文进行策略模式的应用,通过枚举类进行管理(通过注解定义可以看这个设计模式-策略模式+自定义注解应用_蛋炒饭传人的博客-CSDN博客)
目录
2.2.4 定义接口来获取框架自动初始化到IOC 容器对象(用于获取定义好的不同的策略)
1.策略模式介绍
策略模式定义了一系列的算法,并将每一个算法封装起来,使它们可以相互替换。策略模式通常包含以下角色:
- 抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
- 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
- 环境(Context)类:持有一个策略类的引用,最终给客户端调用。
背景:由于博主是做政法行业的,业务中会涉及到诉讼事件,在当事人诉讼过程中会存在 中止案件申请,撤销案件申请,答辩申请等一系列的申请,如果每一个申请写一个接口肯定是不行的,所以第一版通过自定义注解+策略者的模式实现。对于适用的范围相对并列的业务请求。
策略模式适用:出行旅游可以乘坐飞机、乘坐火车、骑自行车或自己开私家车等。超时促销可以采用打折、送商品、送积分等方法。一些相对并列的可选择的事情
2.实现
本文则是定义抽象类,通过继承抽象类进行不同逻辑处理
2.1 逻辑调用图
2.2 具体代码实现
2.2.1 定义抽象类 (主要实现逻辑)
public abstract class ApprovalHandler {
/**
* 提交前置校验
*/
public abstract void preSubmitCheck();
/**
* 提交校验
*/
public abstract void submitCheck();
/**
* 保存报批
*/
public abstract void saveApproval();
/**
*参数传递
*/
public SubmitApprovalReqDTO submitApprovalReqDTO;
public SubmitApprovalReqDTO getSubmitApprovalReqDTO() {
return submitApprovalReqDTO;
}
public void setSubmitApprovalReqDTO(SubmitApprovalReqDTO submitApprovalReqDTO){
this.submitApprovalReqDTO = submitApprovalReqDTO;
}
/**
* 提交参数校验公共方法
*/
public void defaultCheckParam() {
List<SubmitApprovalCaseDTO> approvalCaseList = submitApprovalReqDTO.getApprovalCaseList();
for (SubmitApprovalCaseDTO caseDTO : approvalCaseList) {
Preconditions.checkState(StringUtils.isNotBlank(caseDTO.getDisputeType()), "Dispute type cannot be empty! ");
Preconditions.checkState(Objects.nonNull(caseDTO.getLawCaseId()), "Individual or collective case master case id cannot be empty");
if (! submitApprovalReqDTO.getIsBatch() && StringUtils.equals(DisputeTypeEnum.COLLECTIVE_DISPUTE.name (), caseDTO.getDisputeType())) {
Preconditions.checkState(CollectionUtil.isNotEmpty(caseDTO.getGroupChildCaseIds()), "The child case id checked under the collective case cannot be empty");
}
}
}
}
2.2.2 抽象类实现方法
@Component
public class CaseEndApprovalHandler extends ApprovalHandler {
@Override
public void preSubmitCheck() {
}
@Override
public void submitCheck() {
defaultCheckParam();
}
@Override
public void saveApproval() {
addApproval();
}
}
2.2.3 定义枚举类,管理全部的策略实现类
public enum ApprovalTypeEnum {
CASE_ACCEPT("立案报批", BeanMover.getBean(CaseAcceptApprovalHandler.class)),
CASE_END("结案报批", BeanMover.getBean(CaseEndApprovalHandler.class)),
ABORT("中止审理报批", BeanMover.getBean(SuspendHearApprovalHandler.class));
private String desc;
private ApprovalHandler handler;
ApprovalTypeEnum(String name, ApprovalHandler handler) {
this.desc = name;
this.handler = handler;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public ApprovalHandler getHandler() {
return handler;
}
public void setHandler(ApprovalHandler handler) {
this.handler = handler;
}
}
2.2.4 定义接口来获取框架自动初始化到IOC 容器对象(用于获取定义好的不同的策略)
@Component
public class BeanMover implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.context = applicationContext;
}
public static <T> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}
}
2.2.5 提供对根据枚举类型获取策略类的方法
public class ApprovalHandlerService {
/**
* 生成handler
*/
public static ApprovalHandler createHandler(ApproveCheckReqDTO reqDTO) {
ApprovalHandler handler = ApprovalTypeEnum.valueOf("CASE_ACCEPT").getHandler();
handler.setSubmitApprovalReqDTO(reqDTO);
return handler;
}
}
3. 总结
对于抽象策略的定义 用接口还是用抽象类需要看自己的业务调用,本次采用的抽象类,考虑的是业务中 实现抽象类的方法的前置效验都是一样的,就直接写在抽象类里面了,获取具体策略后则直接写在实现方法里面(2.2.1 和2.2.2)。参数传递则是在抽象类中定义实体类,显示set get方法,在具体的策略类中就可直接使用。