项目中用到了一个订单需要经过多层处理的业务,于是想到了使用链式处理,处理器链中某个节点抛出错误就会中止,如果有事务也是可以回滚的。
核心是使用
@Order
注解和@Configuration
自动配置(可以另外使用单独外观类进行状态)
步骤
定义抽象处理器链
**
* @author SYM
* @date 2022/12/24 20:45
* @Description 抽象处理器链
*/
public abstract class AbstractChain {
/**
* 下一节点
*/
private AbstractChain next;
/**
* 执行链
*
* @param args 参数
*/
public void doChain(Object... args) {
this.handle(args);
// 交由下一节点处理
if (this.next != null) {
this.next.doChain(args);
}
}
/**
* 处理方法
*
* @param args 参数
*/
public abstract void handle(Object... args);
public void setNext(AbstractChain next) {
this.next = next;
}
}
定义类排序常量
用于方便地改动链节点顺序
/**
* @author SYM
* @date 2022/12/24 20:52
* @Description 链表顺序
*/
public class ChainOrder {
public static final int CHAIN_1 = 1;
public static final int CHAIN_2 = 2;
public static final int CHAIN_3 = 3;
}
实现节点
每个节点分别处理一些业务,实现业务解耦
@Order
注解会在@Autowired
等注解自动注入时,如果使用List
、数组
等注入时自动排序。
/**
* @author SYM
* @date 2022/12/24 20:51
* @Description 处理器链1
*/
@Component
@Order(ChainOrder.CHAIN_1)
public class Chain1 extends AbstractChain {
@Override
public void handle(Object... args) {
System.out.println("订单入库");
}
}
/**
* @author SYM
* @date 2022/12/24 20:51
* @Description 处理器链1
*/
@Component
@Order(ChainOrder.CHAIN_2)
public class Chain2 extends AbstractChain {
@Override
public void handle(Object... args) {
System.out.println("优惠计算");
}
}
/**
* @author SYM
* @date 2022/12/24 20:51
* @Description 处理器链1
*/
@Component
@Order(ChainOrder.CHAIN_3)
public class Chain3 extends AbstractChain {
@Override
public void handle(Object... args) {
System.out.println("发起支付");
}
}
装配链表
本质上都是使用自动注入+遍历装配
配置装配
/**
* @author SYM
* @date 2022/12/24 20:55
* @Description
*/
@Configuration
public class ChainConfig {
/**
* 向外返回一个名称的Bean
*
* @param chainList
* @return
*/
@Autowired
@Bean("handleChain")
public AbstractChain handleChain(List<AbstractChain> chainList) {
// 组装链表
Iterator<AbstractChain> iterator = chainList.iterator();
AbstractChain temp = iterator.next();
while (iterator.hasNext()) {
AbstractChain next = iterator.next();
temp.setNext(next);
temp = next;
}
// 返回链表首个节点
return chainList.get(0);
}
}
类装配
/**
* @author SYM
* @date 2022/12/24 21:11
* @Description 处理器链组装,向外固定暴露一个处理器
*/
@Component
public class HandlerChainFacade {
/**
* 链表首个处理节点
*/
private AbstractChain chain;
/**
* 自动创配链表
*
* @param chains
*/
@Autowired
private void autoLoad(AbstractChain... chains) {
List<AbstractChain> chainList = Arrays.asList(chains);
// 组装链表
Iterator<AbstractChain> iterator = chainList.iterator();
AbstractChain temp = iterator.next();
while (iterator.hasNext()) {
AbstractChain next = iterator.next();
temp.setNext(next);
temp = next;
}
this.chain = chainList.get(0);
}
/**
* 处理方法
*
* @param args 参数
*/
public void doChain(Object... args) {
this.chain.doChain(args);
}
}
结语
作者认为,开发过程中,有意无意地使用设计模式是一种非常好的编码习惯。合理使用设计模式可以使代码更加简洁、业务逻辑更加分明,整体逻辑更加清晰。
如果各位有其他更好的想法或者问题,欢迎在留下您宝贵的评论,愿能在代码路上共同进步!