最近正在做工单系统,每种类型工单的操作是相似的但是又有不同,比如工单审批是相同的,但是工单启动是不同的,因此自然而然想到把工单的操作放到一个抽象类中,每种工单实现不同的操作。
工单服务抽象类ProcessInstanceService
@Servicepublic abstract class ProcessInstanceService{ public abstract String start(BaseParamDTO baseParamDTO); public void approval(BaseParamDTO baseParamDTO, String user) { System.out.println("审批通过"); }}复制代码
现在有一种扩容工单和一种权限申请工单
@Servicepublic class ExpansionService extends ProcessInstanceService{ @Override public String start(BaseParamDTO baseParamDTO) { System.out.println("扩容"); }}@Servicepublic class PrivilegeService extends ProcessInstanceService{ @Override public String start(BaseParamDTO baseParamDTO) { System.out.println("权限申请"); }} 复制代码
前端启动工单,这个时候需要根据工单类型获取对应的服务进行操作,因此使用了工厂模式
public enum WorksheetTypeEnum { EXPANSION("扩容", "machine_expansion"), PRIVILEGE("登录权限","privilege_login"); private String cnName; private String activitiDefineName; WorksheetTypeEnum(String cnName, String activitiDefineName){ this.cnName = cnName; this.activitiDefineName = activitiDefineName; }}@Componentpublic class ProcessInstanceFactory { @Autowired private ExpansionService expansionService; @Autowired private PrivilegeService privilegeService; public ProcessInstanceService getProcessInstanceService(WorksheetTypeEnum worksheetTypeEnum){ switch (worksheetTypeEnum){ case EXPANSION: return expansionService; case PRIVILEGE: return privilegeService; default: return null; } }}复制代码
当前的代码已经使用枚举简化了if else,但是仍然存在问题,当新增一种工单时,ProcessInstanceFactory必须注入新的工单服务,然后添加新的case。那有没有什么方法不用修改工厂类直接添加新的工单类型呢,那就是使用注解。
首先创建一个注解
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface ServiceTypeAnnotation { /** * 工单类型名称 * @return */ WorksheetTypeEnum value();}复制代码
为每个工单服务加上注解
@Service@ServiceTypeAnnotation(value = WorksheetTypeEnum.EXPANSION)public class ExpansionService extends ProcessInstanceService{}@Service@ServiceTypeAnnotation(value = WorksheetTypeEnum.PRIVILEGE)public class PrivilegeService extends ProcessInstanceService{}复制代码
修改工厂类ProcessInstanceFactory,在初始化的时候通过上下文拿到所有加了注解的类放到map中
@Componentpublic class ProcessInstanceFactory { @Autowired private DefaultService defaultService; @Autowired private ApplicationContext applicationContext; private Mapmap = Maps.newConcurrentMap(); @PostConstruct public void init(){ Map beansWithAnnotation = applicationContext.getBeansWithAnnotation(ServiceTypeAnnotation.class); for (Object bean : beansWithAnnotation.values()){ ServiceTypeAnnotation annotation = bean.getClass().getAnnotation(ServiceTypeAnnotation.class); map.put(annotation.value(), (ProcessInstanceService) bean); } } public ProcessInstanceService getProcessInstanceService(WorksheetTypeEnum worksheetTypeEnum){ ProcessInstanceService processInstanceService = map.get(worksheetTypeEnum); if (processInstanceService == null){ return defaultService; } else { return processInstanceService; } }复制代码
这样如果需要新增一个工单服务,只需要对新的类加上注解就可以了,如新增一个手工工单
public enum WorksheetTypeEnum { EXPANSION("扩容", "machine_expansion"), PRIVILEGE("登录权限","privilege_login"), ASSIGNMENT("手工工单", "assignments"); }@Service@ServiceTypeAnnotation(value = WorksheetTypeEnum.ASSIGNMENT)public class AssignmentService extends ProcessInstanceService{}复制代码