设计模式-责任链设计模式理解与实例

责任链模式是一种行为设计模式, 允许你将请求沿着处理者链进行发送。收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。
我的理解就是:用来处理一系列的流程,一步一步地往下走,每一步就是一个责任节点。
使用场景: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、审批链(责任链)审批不通过结果:
我想要请假结婚!
组长不同意,说要加班
审批不通过,责任链断掉,审批流不再继续向下进行

你可能感兴趣的:(设计模式-责任链设计模式理解与实例)