状态改变之责任链模式
场景描述:
最近有个关于新增流程审批的项目,要按一定的流程顺序实现状态修改。
按照最原始的实现方式就是拿到当前状态然后判断需要执行的步骤继续执行。这个弊端就是会存在有许多的判断和重复代码;
V.1.0的实现 :
为了快速实现该功能,就采用了分段实现各个流程功能,然后根据状态判断需要执行的流程,组合实现
弊端:代码又臭又长,重复性高,不容易扩展
V.2.0的实现 :
功能实现后,还有时间便开始考虑重构代码。正常来说面向对象编程,要实现易扩展,就可以套用相应的设计模式。而我要实现的功能其实很明显用责任链模式就可以实现程序的扩展,而且也是符合实际的。
于是开始着手用责任链的模式改造代码。https://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html (菜鸟教程,责任链模式)
首先要定义一个抽象的处理类,定义责任链的下一级处理对象。其他一些具体的需要可根据自己的需求添加;
其次根据流程定义所需要的子类具体实现
最后定义一个处理链配置;初始化相关的责任链,比如设置下一级处理人,以及当前需要从哪个流程开始处理。
实现如下:
/**
* 获取当前
*
* @param supplierStatusEnum
* @return
*/
public KindDeeResponse doAddSupplier(SupplierStatusEnum supplierStatusEnum) {
public KindDeeResponse doAddSupplier(SupplierStatusEnum supplierStatusEnum, ContractLessorInfoAO contractLessorInfoAO,String key) throws Exception {
switch (supplierStatusEnum) {
case SAVE:
return saveHandler.addSupplier(contractLessorInfoAO,key);
case COMMIT:
return commitHandler.addSupplier(contractLessorInfoAO,key);
case AUDIT:
return auditHandler.addSupplier(contractLessorInfoAO,key);
case ALLOCATE:
return auditHandler.addSupplier(contractLessorInfoAO,key);
}
return new KindDeeResponse();
}
/**
* 初始化新增链
*/
@PostConstruct
public void initChain() {
saveHandler.setNextHandler(commitHandler);
commitHandler.setNextHandler(auditHandler);
auditHandler.setNextHandler(assignHandler);
}
弊端:责任链的初始化写的太死板,不容易扩展。如果要加个状态还需要改动责任链,同时还要加一个对应的实现类。这种就像处理链采用的是简单工厂的模式,不利于新增扩展。
V.2.1的实现 :
利用spring的@Order注解,指定类的执行顺序。这样只需要控制顺序,就能达到按我们定义的顺序执行。
所以在V.2.0的各个实现类种加一个@Order注解指定顺序,以及对最后一步进行改造:
重新定义一个处理链配置;具体实现如下:
/**
*初始化责任链
*/
@PostConstruct
private void initHandlerChains() {
Collections.sort(handlerChains, AnnotationAwareOrderComparator.INSTANCE);
int size = handlerChains.size();
for (int i = 0; i < size; i++) {
if (i == size - 1) {
handlerChains.get(i).setNextHandler(null);
} else {
handlerChains.get(i).setNextHandler(handlerChains.get(i + 1));
}
}
}
/**
* 获取当前
*
* @param supplierStatusEnum
* @return
*/
public KindDeeResponse doAddSupplier(SupplierStatusEnum supplierStatusEnum, ContractLessorInfoAO contractLessorInfoAO) throws Exception {
//如果是新增
if(supplierStatusEnum==SupplierStatusEnum.NEW){
return handlerChains.get(0).addSupplier(contractLessorInfoAO);
}
//中间的某一个环节
for(AbstractHandler handler :handlerChains){
if(handler.getSupplierStatusEnum()==supplierStatusEnum){
if(null!=handler.nextHandler){
handler = handler.nextHandler;
}
return handler.addSupplier(contractLessorInfoAO);
}
}
return null;
}
至此,基于Spring框架下的责任链模式实现状态转换就完成了。