责任链模式:动态组装不同的复杂业务流程
什么时候用责任链模式呢?就是如果你需要动态组装一个业务流程出来,流程中的每个handler业务逻辑需要复用,那就用责任链模式。
首先,每个流程是一个独立的逻辑
其次,流程之间有先后顺序,上一个成功再下一个。

一环接一环,就适合用责任链模式。
由上一个流程的实现类依赖并调用下一个流程的实现类,进入下一个流程处理。

需求背景
在调度中心,一笔采购入库单一旦审核通过之后,就需要
对这个采购单进行一系列的处理。
步骤流程如下:

1、通知调度中心:更新自己本地的状态、将采购入库单的状态变为已入库,更新自己本地的库存、 新增自己本地的货位库存明细
2、通知采购中心:更新采购单的状态
3、通知财务中心:创建采购结算单

我们可以把以上3个步骤封装为3个Handler,然后上一个Handler依赖注入下一个流程的Handler,处理完后调用下一个的处理方法。就组成一个责任链模式。

优点:以后流程有增加或者减少,只需要修改增加or减少责任链链条的长度即可,上层的逻辑不需要做任何改动。
需求实现
定义一个流程处理接口

/**
 * 采购入库单处理的handler接口
 * @author
 *
 */
public interface PurchaseInputOrderHandler {

	/**
	 * 执行处理逻辑
	 * @param purchaseInputOrder 采购入库单
	 * @return 处理结果
	 * @throws Exception
	 */
	Boolean execute(PurchaseInputOrderDTO purchaseInputOrder) throws Exception;
	
}**

封装一个结果类保存每个环节的处理结果:

/**
 * 采购入库单处理结果
 * @author 
 *
 */
public class PurchaseInputOrderHandlerResult {

	/**
	 * 处理结果
	 */
	private Boolean result;
	/**
	 * 是否执行下一个handler
	 */
	private Boolean doNext = true;
	
	public PurchaseInputOrderHandlerResult(Boolean result) {
		this.result = result;
	}

	public PurchaseInputOrderHandlerResult(Boolean result, Boolean doNext) {
		this.result = result;
		this.doNext = doNext;
	}

	public Boolean getResult() {
		return result;
	}

	public void setResult(Boolean result) {
		this.result = result;
	}

	public Boolean getDoNext() {
		return doNext;
	}

	public void setDoNext(Boolean doNext) {
		this.doNext = doNext;
	}
	
}

对接口实现一个抽象基类,组织责任链模式,抽象基类中完成的逻辑:
1、执行本环节处理流程并get本环节的结果
2、判断是否有下一个环节或者是否需要执行下个环节。
3、调用下一个环节的handler或者返回结果

/**
 * 采购入库单处理handler的抽象基类
 * @author 
 *
 */
public abstract class AbstractPurchaseInputOrderHandler implements PurchaseInputOrderHandler {

	/**
	 * 下一个采购入库单处理handler
	 */
	protected PurchaseInputOrderHandler successor;
	
	/**
	 * 执行下一个handler
	 * @param purchaseInputOrder 采购入库单
	 * @return 处理结果
	 * @throws Exception
	 */
	public Boolean execute(PurchaseInputOrderDTO purchaseInputOrder) throws Exception {
		PurchaseInputOrderHandlerResult result = doExecute(purchaseInputOrder);
			//是否还有下一个环节,是否还需要继续下一个环节
		if(successor != null && result.getDoNext()) { 
			return successor.execute(purchaseInputOrder);
		} else {
			return result.getResult();
		}
	}
	
	/**
	 * 执行当前handler的处理逻辑
	 * @param purchaseInputOrder 采购入库单 
	 * @return 处理结果
	 * @throws Exception
	 */
	protected abstract PurchaseInputOrderHandlerResult doExecute(
			PurchaseInputOrderDTO purchaseInputOrder) throws Exception;  

	public PurchaseInputOrderHandler getSuccessor() {
		return successor;
	}

	public void setSuccessor(PurchaseInputOrderHandler successor) {
		this.successor = successor;
	}
	
}

继承抽象基类 AbstractPurchaseInputOrderHandler
实现需求中的3个实现类:
1、通知调度中心实现类-InformScheduleCenterHandler
2、通知采购中心实现类-InformPurchaseCenterHandler
3、通知财务中心实现类-InformFinanceCenterHandler

/**
 * 通知调度中心的handler
 * @author 
 *
 */
@Component
public class InformScheduleCenterHandler extends AbstractPurchaseInputOrderHandler {

	/**
	 * 调度中心接口
	 */
	@Autowired
	private ScheduleService scheduleService;
	
	/**
	 * 执行处理逻辑
	 */
	public PurchaseInputOrderHandlerResult doExecute(
			PurchaseInputOrderDTO purchaseInputOrder) throws Exception {
		scheduleService.informPurchaseInputFinished(purchaseInputOrder);
		return new PurchaseInputOrderHandlerResult(true); 
	}

}
/**
 * 通知采购中心的handler
 * @author 
 *
 */
@Component
public class InformPurchaseCenterHandler extends AbstractPurchaseInputOrderHandler {
	
	/**
	 * 采购中心接口
	 */
	@Autowired
	private PurchaseService purchaseService;
	
	/**
	 * 执行处理逻辑
	 */
	public PurchaseInputOrderHandlerResult doExecute(
			PurchaseInputOrderDTO purchaseInputOrder) throws Exception {
		purchaseService.informFinishedPurchaseInputOrderEvent(
				purchaseInputOrder.getPurchaseInputOrderId());
		return new PurchaseInputOrderHandlerResult(true); 
	}

}
/**
 * 通知财务中心的handler
 * @author 
 *
 */
@Component
public class InformFinanceCenterHandler extends AbstractPurchaseInputOrderHandler {

	/**
	 * 财务中心接口
	 */
	@Autowired
	private FinanceService financeService;
	
	/**
	 * 执行处理结果
	 */
	public PurchaseInputOrderHandlerResult doExecute(
			PurchaseInputOrderDTO purchaseInputOrder) throws Exception {
		financeService.createPurchaseSettlementOrder(purchaseInputOrder);
		return new PurchaseInputOrderHandlerResult(true); 
	}

}

组装责任链
以上三个具体实现类,就是责任链的三个节点。
我们封装一个工厂类在构造函数PurchaseInputOrderHandlerFactory() 中把
三个节点组装成责任链,并暴露一个获取链条第一个节点的方法
public PurchaseInputOrderHandler getHandlerChain()

/**
 * 采购入库单handler工厂
 * @author 
 *
 */
@Component
public class PurchaseInputOrderHandlerFactory {

	/**
	 * 更新采购入库单状态handler
	 */
	@Autowired
	private UpdatePurchaseInputOrderStatusHandler updatePurchaseInputOrderStatusHandler;
	/**
	 * 通知采购中心handler
	 */
	@Autowired
	private InformPurchaseCenterHandler informPurchaseCenterHandler;
	/**
	 * 更新本地库存handler
	 */
	@Autowired
	private UpdateStockHandler updateStockHandler;
	/**
	 * 通知调度中心handler
	 */
	@Autowired
	private InformScheduleCenterHandler informScheduleCenterHandler;
	/**
	 * 通知财务中心handler
	 */
	@Autowired
	private InformFinanceCenterHandler informFinanceCenterHandler;
	
	/**
	 * 构造函数:组装责任链条
	 */
	public PurchaseInputOrderHandlerFactory() {
		updatePurchaseInputOrderStatusHandler.setSuccessor(informPurchaseCenterHandler);
		informPurchaseCenterHandler.setSuccessor(updateStockHandler);
		updateStockHandler.setSuccessor(informScheduleCenterHandler); 
		informScheduleCenterHandler.setSuccessor(informFinanceCenterHandler); 
	}
	
	/**
	 * 创建采购入库单handler链条
	 * @param purchaseInputOrder 采购入库单
	 * @return handler链条
	 * @throws Exception
	 */
	public PurchaseInputOrderHandler getHandlerChain() throws Exception {
		return updatePurchaseInputOrderStatusHandler;
	}
	
}

上层使用:
购入库单管理service 的审核方法中 approve
如果审核通过、则通过责任链处理接下来的流程。
流程如果有变,上层使用不需要做任何修改。

/**
 * 采购入库单管理service组件
 * @author 
 *
 */
@Service
@Transactional
public class PurchaseInputOrderServiceImpl implements PurchaseInputOrderService {

	/**
	 * 采购入库单handler工厂
	 */
	@Autowired
	private PurchaseInputOrderHandlerFactory handlerFactory;
	
	
	/**
	 * 审核采购入库单
	 * @param id 采购入库单id
	 * @param approveResult 审核结果
	 * @throws Exception
	 */
	public void approve(Long id, Integer approveResult) throws Exception {
		if(PurchaseInputOrderApproveResult.REJECTED.equals(approveResult)) {
			purchaseInputOrderDAO.updateStatus(id, PurchaseInputOrderStatus.EDITING);  
			return;
		}
		
		//如果审核通过、则通过责任链处理接下来的流程
		if(PurchaseInputOrderApproveResult.PASSED.equals(approveResult)) {
			PurchaseInputOrderDTO purchaseInputOrder = getById(id);
			PurchaseInputOrderHandler handlerChain = handlerFactory.getHandlerChain();
			handlerChain.execute(purchaseInputOrder);
		}
	}
	
}