https://preparedata.blog.csdn.net/article/details/134512591
个人理解责任链模式在于,将业务功能拆分成各节点(职责节点),再打包成有顺序性的链路。
如果节点处理成功,可进入下一节点 。以下示例代码未包含此逻辑,但可在基类中添加状态来实现,偷个懒,暂不实现了。
案例一:订单创建
订单创建,可能会包含参数检查、锁定库存、优惠券核销、积分抵扣、处理购物车、订单消息通知
等逻辑
但不同的订单类型可能包含的节点不同或顺序。现在可以将订单创建逻辑拆分。
不同的订单类型 可以提现设置不同的执行链路来处理订单。
如后续需添加节点或删除节点。也能快速适配
案例一:审批
审批流程,可能会包含组长、经理、行政、老板
等逻辑
但不同的审批业务可能包含的节点不同或顺序。现在可以将逻辑拆分。
不同的审批业务 可以提现设置不同的执行链路来处理。
利用泛型 T
来约束子类中需继承ResponsibilityChainPathExecute
利用泛型 P
来泛型化处理节点执行的参数, 实际业务中,可以将订单创建、审批相差很大的业务使用上下文来处理节点执行的参数
链路节点执行使用了递归
invoke(ResponsibilityChainPathExecute nextChain, P p) ,所以在组装链路时,需要保证链路有始有终,不能循环依赖
package com.pd.shopping.order.designptern.chain;
/**
* @author hl
*/
public class ResponsibilityChain<T extends ResponsibilityChainPathExecute, P> {
/**
* 责任链的开始节点
*/
private T executeChain;
/**
* 构造函数
* @param startChain 责任链的开始节点
*/
public ResponsibilityChain(T startChain) {
executeChain = startChain;
}
/**
* 责任链的调用
* @param p 执行方法的泛型参数
*/
public void invoke(P p) {
if(executeChain == null){
return;
}
executeChain.execute(p);
ResponsibilityChainPathExecute nextChain = executeChain.getNextChain();
if(nextChain == null){
return;
}
this.invoke(nextChain,p);
}
/**
* 责任链后续节点执行 递归执行
*
* @param nextChain 责任链下一个节点
* @param p 执行方法的泛型参数
*/
private void invoke(ResponsibilityChainPathExecute nextChain, P p) {
if(nextChain == null){
return;
}
nextChain.execute(p);
ResponsibilityChainPathExecute nextChain1 = nextChain.getNextChain();
if(nextChain1 == null){
return;
}
this.invoke(nextChain1, p);
}
}
需要使用责任链,都该继承ResponsibilityChainPathExecute,用来处理各节点的顺序执行
package com.pd.shopping.order.designptern.chain;
import org.springframework.stereotype.Component;
/**
* @author hl
*/
@Component
public abstract class ResponsibilityChainPathExecute<P> {
/**
* 责任链中节点执行方法
* @param p 执行方法的泛型参数
*/
public abstract void execute(P p);
/**
*
*/
private ResponsibilityChainPathExecute nextChain;
/**
* 设置 责任链下一个节点
* @param next 下一个节点
*/
public void setNextChain(ResponsibilityChainPathExecute next){
this.nextChain = next;
}
/**
* 获取 责任链下一个节点
*
* @return ResponsibilityChainPathExecute 执行器
*/
public ResponsibilityChainPathExecute getNextChain(){
return this.nextChain;
}
}
链路节点执行使用了递归
,所以在组装链路时,需要保证链路有始有终,不能循环依赖
SpringApplicationUtil为获取Bean的工具类,暂不提供,但可以用new 创建一个Bean
package com.pd.shopping.order.designptern.chain.order;
import com.pd.shopping.common.SpringApplicationUtil;
import com.pd.shopping.order.designptern.chain.*;
import org.springframework.stereotype.Component;
/**
* @author hl
*/
@Component
public abstract class AbstractChainOrder<P> extends ResponsibilityChainPathExecute<P> {
public static AbstractChainOrder chainPath(){
//链开始节点 startCheck
AbstractChainOrder startCheck = SpringApplicationUtil.getBean(ChainOrderCheck.class);
AbstractChainOrder stock = SpringApplicationUtil.getBean(ChainOrderStock.class);
AbstractChainOrder coupon = SpringApplicationUtil.getBean(ChainOrderCoupon.class);
AbstractChainOrder integral = SpringApplicationUtil.getBean(ChainOrderIntegral.class);
AbstractChainOrder shoppingCart = SpringApplicationUtil.getBean(ChainOrderShoppingCart.class);
//链结束节点 endMsg
AbstractChainOrder endMsg = SpringApplicationUtil.getBean(ChainOrderMsg.class);
//链结束节点 endMsg
shoppingCart.setNextChain(endMsg);
integral.setNextChain(shoppingCart);
coupon.setNextChain(integral);
stock.setNextChain(coupon);
//链开始节点 startCheck
startCheck.setNextChain(stock);
return startCheck;
}
public static AbstractChainOrder chainPath2(){
//链开始节点 startCheck
AbstractChainOrder startCheck = SpringApplicationUtil.getBean(ChainOrderCheck.class);
AbstractChainOrder stock = SpringApplicationUtil.getBean(ChainOrderStock.class);
//链结束节点 endMsg
AbstractChainOrder endMsg = SpringApplicationUtil.getBean(ChainOrderMsg.class);
stock.setNextChain(endMsg);
startCheck.setNextChain(stock);
return startCheck;
}
}
package com.pd.shopping.order.designptern.chain.order;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author hl
*/
@Component
public class ChainOrderCheck extends AbstractChainOrder<Map<String, Object>> {
@Override
public void execute(Map<String, Object> map) {
System.out.println("ChainOrderCheck 参数检查," + map.get("goodsName").toString());
}
}
package com.pd.shopping.order.designptern.chain.order;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author hl
*/
@Component
public class ChainOrderCoupon extends AbstractChainOrder<Map<String, Object>> {
@Override
public void execute(Map<String, Object> map) {
System.out.println("ChainOrderCoupon 优惠券核销," + map.get("goodsName").toString());
}
}
package com.pd.shopping.order.designptern.chain.order;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author hl
*/
@Component
public class ChainOrderIntegral extends AbstractChainOrder<Map<String, Object>> {
@Override
public void execute(Map<String, Object> map) {
System.out.println("ChainOrderIntegral 积分抵扣," + map.get("goodsName").toString());
}
}
package com.pd.shopping.order.designptern.chain.order;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author hl
*/
@Component
public class ChainOrderMsg extends AbstractChainOrder<Map<String, Object>> {
@Override
public void execute(Map<String, Object> map) {
System.out.println("ChainOrderMsg 订单消息通知," + map.get("goodsName").toString());
}
}
package com.pd.shopping.order.designptern.chain.order;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author hl
*/
@Component
public class ChainOrderShoppingCart extends AbstractChainOrder<Map<String, Object>> {
@Override
public void execute(Map<String, Object> map) {
System.out.println("ChainOrderShoppingCart 处理购物车," + map.get("goodsName").toString());
}
}
package com.pd.shopping.order.designptern.chain.order;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author hl
*/
@Component
public class ChainOrderStock extends AbstractChainOrder<Map<String, Object>> {
@Override
public void execute(Map<String, Object> map) {
System.out.println("ChainOrderStock 锁定库存," + map.get("goodsName").toString());
}
}
链路节点执行使用了递归
,所以在组装链路时,需要保证链路有始有终,不能循环依赖
package com.pd.shopping.order.designptern.chain.approve;
import com.pd.shopping.common.SpringApplicationUtil;
import com.pd.shopping.order.designptern.chain.ResponsibilityChainPathExecute;
import org.springframework.stereotype.Component;
/**
* @author hl
*/
@Component
public abstract class AbstractChainApprove<P> extends ResponsibilityChainPathExecute<P> {
public static AbstractChainApprove chainPath(){
//链开始节点 startLeader
AbstractChainApprove startLeader = SpringApplicationUtil.getBean(ChainApproveLeader.class);
//链结束节点 endBoos
AbstractChainApprove endBoos = SpringApplicationUtil.getBean(ChainApproveBoos.class);
//链开始节点 startLeader
startLeader.setNextChain(endBoos);
return startLeader;
}
}
package com.pd.shopping.order.designptern.chain.approve;
import com.pd.shopping.order.model.bo.ApproveContext;
import org.springframework.stereotype.Component;
/**
* @author hl
*/
@Component
public class ChainApproveBoos extends AbstractChainApprove<ApproveContext> {
@Override
public void execute(ApproveContext context) {
System.out.println("ChainApproveBoos 老板审批," + context.getBoosName());
}
}
package com.pd.shopping.order.designptern.chain.approve;
import com.pd.shopping.order.model.bo.ApproveContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @author hl
*/
@Slf4j
@Component
public class ChainApproveLeader extends AbstractChainApprove<ApproveContext> {
@Override
public void execute(ApproveContext context) {
System.out.println("ChainApproveBoos 经理审批," + context.getLeaderName());
}
}
@GetMapping("/chainOrder")
public void chainOrder() {
System.out.println("订单创建,链路1:");
//下单参数
Map<String,Object> map1 = new HashMap<>();
map1.put("goodsName","比亚迪");
//链路
AbstractChainOrder chain1 = AbstractChainOrder.chainPath();
ResponsibilityChain responsibilityChain1 = new ResponsibilityChain<AbstractChainOrder, Map<String,Object>>(chain1);
responsibilityChain1.invoke(map1);
System.out.println("订单创建,链路2:");
Map<String,Object> map2 = new HashMap<>();
map2.put("goodsName","长城");
AbstractChainOrder chain2 = AbstractChainOrder.chainPath2();
ResponsibilityChain responsibilityChain2 = new ResponsibilityChain<AbstractChainOrder, Map<String,Object>>(chain2);
responsibilityChain2.invoke(map2);
/* ********************************************************************** */
System.out.println("审批,链路2:");
ApproveContext approveContext = new ApproveContext();
approveContext.setBoosName("张老板");
approveContext.setLeaderName("李经理");
AbstractChainApprove chainApprove = AbstractChainApprove.chainPath();
ResponsibilityChain responsibilityChain3 = new ResponsibilityChain<AbstractChainApprove, ApproveContext>(chainApprove);
responsibilityChain3.invoke(approveContext);
}
执行日志
订单创建,链路1:
ChainOrderCheck 参数检查,比亚迪
ChainOrderStock 锁定库存,比亚迪
ChainOrderCoupon 优惠券核销,比亚迪
ChainOrderIntegral 积分抵扣,比亚迪
ChainOrderShoppingCart 处理购物车,比亚迪
ChainOrderMsg 订单消息通知,比亚迪
订单创建,链路2:
ChainOrderCheck 参数检查,长城
ChainOrderStock 锁定库存,长城
ChainOrderMsg 订单消息通知,长城
审批,链路2:
ChainApproveBoos 经理审批,李经理
ChainApproveBoos 老板审批,张老板