责任链模式是一种行为设计模式, 允许你将请求沿着处理者链进行发送。收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。
我的理解就是:用来处理一系列的流程,一步一步地往下走,每一步就是一个责任节点。
使用场景:1、流程审批 2、权限控制
适用的场景很多很多,个人感觉只要是步骤多的场景都可以使用,本文例子采用了流程审批的场景。
一、简单责任链实例
package designmode.responsibilitychainmode.simple;
/**
* 审批处理器
* @author pcf
* @date 2023/3/13 9:47
*/
abstract class AbstractHandler {
// 下一个审批节点
private AbstractHandler nextHandler;
// 设置下一个审批节点
public void setNextHandler(AbstractHandler nextHandler) {
this.nextHandler = nextHandler;
}
public AbstractHandler getNextHandler() {
return nextHandler;
}
// 审批
public abstract void handler();
}
class FirstHandler extends AbstractHandler {
@Override
public void handler() {
int random = (int)(Math.random()*100);
// 随机模拟审批通过或不通过之后的流程走向
if (random % 2 == 0) {
System.out.println("组长已审批");
if (getNextHandler() != null) {
// 处理完成,审批单传递给下一步处理人
getNextHandler().handler();
}
} else {
System.out.println("组长不同意,说要加班");
System.out.println("审批不通过,责任链断掉,审批流不再继续向下进行");
}
}
}
class SecHandler extends AbstractHandler {
@Override
public void handler() {
System.out.println("项目经理已审批");
if (getNextHandler() != null) {
// 处理完成,审批单传递给下一步处理人
getNextHandler().handler();
}
}
}
class ThirdHandler extends AbstractHandler {
@Override
public void handler() {
System.out.println("行政部已审批,审批流程完毕,回家结婚去吧!");
if (getNextHandler() != null) {
// 处理完成,审批单传递给下一步处理人
getNextHandler().handler();
}
}
}
使用责任链
package designmode.responsibilitychainmode.simple;
import org.junit.Test;
/**
* @author pcf
* @date 2023/3/13 10:44
*/
public class TestRes {
@Test
public void testRes() {
System.out.println("我想要请假结婚!");
FirstHandler firstHandler = new FirstHandler(); // 第一个审批人
SecHandler secHandler = new SecHandler(); // 第二个审批人
ThirdHandler thirdHandler = new ThirdHandler(); // 第三个审批人
firstHandler.setNextHandler(secHandler); // 第一个审批人的后续处理人是第二个审批人
secHandler.setNextHandler(thirdHandler); // 第二个审批人的后续处理人是第三个审批人,审批链完成
firstHandler.handler(); // 开始审批
}
}
结果分析:
1、审批链(责任链)审批成功结果:
我想要请假结婚!
组长已审批
项目经理已审批
行政部已审批,审批流程完毕,回家结婚去吧!
2、审批链(责任链)审批不通过结果:
我想要请假结婚!
组长不同意,说要加班
审批不通过,责任链断掉,审批流不再继续向下进行
可以看FirstHandler类中的处理逻辑,如果本步审批成功,会向下一步发起流程审批。
如果本步审批失败,则审批链断掉,结束。
看完实例,责任链还是很好理解的。每个责任节点包含有它下一个责任节点的引用,处理完一个责任节点的业务后,继续进入向下一个责任节点,直到最后一个节点。
实现起来还是很啰嗦的,因为需要对每一个责任节点创建该节点的处理器,再把后面节点的引用赋给前一个节点。显得代码很冗余,还很不好看。
因此可以一些方法将这个组合责任链的过程优化一下,最好是能够动态生成,可手动配置。这样一来针对不同的业务需要,组装不同的责任链。
二、利用枚举动态组装责任链
package designmode.responsibilitychainmode.resfactory;
/**
* 审批处理器
* @author pcf
* @date 2023/3/13 9:47
*/
abstract class AbstractHandler {
// 下一个审批节点
private AbstractHandler nextHandler;
// 设置下一个审批节点
public void setNextHandler(AbstractHandler nextHandler) {
this.nextHandler = nextHandler;
}
public AbstractHandler getNextHandler() {
return nextHandler;
}
// 审批
public abstract void handler();
}
package designmode.responsibilitychainmode.resfactory;
/**
* 组长审批
*/
public class HeadmanHandler extends AbstractHandler {
@Override
public void handler() {
int random = (int)(Math.random()*100);
// 随机模拟审批通过或不通过之后的流程走向
if (random % 2 == 0) {
System.out.println("组长已审批");
if (getNextHandler() != null) {
// 处理完成,审批单传递给下一步处理人
getNextHandler().handler();
}
} else {
System.out.println("组长不同意,说要加班");
System.out.println("审批不通过,责任链断掉,审批流不再继续向下进行");
}
}
}
package designmode.responsibilitychainmode.resfactory;
/**
* 行政部审批
*/
class ManagerHandler extends AbstractHandler {
@Override
public void handler() {
System.out.println("项目经理已审批");
if (getNextHandler() != null) {
// 处理完成,审批单传递给下一步处理人
getNextHandler().handler();
}
}
}
package designmode.responsibilitychainmode.resfactory;
/**
* 行政部审批
*/
class HrHandler extends AbstractHandler {
@Override
public void handler() {
System.out.println("行政部已审批,审批流程完毕,回家结婚去吧!");
if (getNextHandler() != null) {
// 处理完成,审批单传递给下一步处理人
getNextHandler().handler();
}
}
}
package designmode.responsibilitychainmode.resfactory;
/**
* @author pcf
* @date 2023/3/13 11:31
*/
public enum ChainEnum {
HEADMAN_HANDLER(1, "designmode.responsibilitychainmode.resfactory.HeadmanHandler"),
MANAGER_HANDLER(2, "designmode.responsibilitychainmode.resfactory.ManagerHandler"),
HR_HANDLER(3, "designmode.responsibilitychainmode.resfactory.HrHandler");
private final int id;
private final String className;
ChainEnum(int id, String className) {
this.id = id;
this.className = className;
}
public int getId() {
return id;
}
public String getClassName() {
return className;
}
private static String getClassName(int id) {
for (ChainEnum enu : ChainEnum.values()) {
if (enu.getId() == id) {
return enu.getClassName();
}
}
return "";
}
// 婚嫁审批流节点
private static int[] weddingProcess = {1,2,3};
// 事假审批流节点
private static int[] thingProcess = {1,2};
// 组转审批链
public static void startWeddingProcess() throws IllegalAccessException, InstantiationException, ClassNotFoundException {
AbstractHandler[] handlers = new AbstractHandler[3];
for (int i = 0; i < weddingProcess.length; i++) {
Class> aClass = Class.forName(getClassName(i+1));
AbstractHandler handler = (AbstractHandler)aClass.newInstance();
handlers[i] = handler;
if (i>=1 && handlers[i - 1] != null) {
handlers[i-1].setNextHandler(handlers[i]);
}
}
handlers[0].handler();
}
}
package designmode.responsibilitychainmode.resfactory;
import org.junit.Test;
/**
* @author pcf
* @date 2023/3/13 10:44
*/
public class TestRes {
@Test
public void testRes() throws IllegalAccessException, ClassNotFoundException, InstantiationException {
System.out.println("我想要请假结婚!");
ChainEnum.startWeddingProcess();
}
}
// 结果
1、审批链(责任链)审批成功结果:
我想要请假结婚!
组长已审批
项目经理已审批
行政部已审批,审批流程完毕,回家结婚去吧!
2、审批链(责任链)审批不通过结果:
我想要请假结婚!
组长不同意,说要加班
审批不通过,责任链断掉,审批流不再继续向下进行