设计模式之责任链

概述

责任链模式(Chain of Responsibility Pattern)属于行为型设计模式。它为请求创建了一个处理链条,这个链条上的所有对象都要对这个请求进行处理。比如我们生活中经常使用的审批流程,当每一个节点审批通过后,发送给下一个节点,如:开发小组长->部门领导->总经理。也可以和java中的链表进行类比。

使用场景

  1. 当一个请求需要进行一系列的处理的时候,如:数据处理过程需要进行数据抽取、清洗、转换、存储
  2. 比如工作流审批场景

如何实现

以审批流程为例,如何进行抽象设计:

  1. 所有对象都具有审批行为,将其作为一个抽象方法doApproval()
  2. 所有对象都具有传递行为,将需要审批的单据传递给下一个审批人。而传递的逻辑都是一样的,所以将传递行为定义为一个默认的方法delivery()
  3. 既然需要传递,那么就要知道下一个审批人是谁。所以将下一个审批人作为一个成员属性

代码示例

审批人抽象

/**
 * 审批人抽象
 */
public abstract class Approver {

    private Approver nextApprover;

    /**
     * 审批逻辑
     * @param money
     */
    abstract void doApproval(int money);

    /**
     * 责任链传递方法
     * @param money
     */
    protected void delivery(int money) {
        if (nextApprover == null) {
            System.out.println("结束::没有下一个审批人了");
        } else {
            nextApprover.doApproval(money);
        }
    }

    public Approver getNextApprover() {
        return nextApprover;
    }

    public void setNextApprover(Approver nextApprover) {
        this.nextApprover = nextApprover;
    }
}

小组长审批实现

/**
 * 小组长审批实现
 */
public class TeamLeaderApprover extends Approver {

    @Override
    public void doApproval(int money) {
        if (money <= 5000) {
            System.out.println("TeamLeader::审批通过::交给下一个审批人");
        } else {
            System.out.println("TeamLeader::没有权限::交给下一个审批人");
        }
        this.delivery(money);
    }
}

部门领导审批实现

/**
 * 部门领导审批实现
 */
public class DeptLeaderApprover extends Approver {

    @Override
    public void doApproval(int money) {
        if (money <= 10000) {
            System.out.println("DeptLeader::审批通过::交给下一个审批人");
        } else {
            System.out.println("DeptLeader::没有权限::交给下一个审批人");
        }
        this.delivery(money);
    }
}

CEO审批实现

/**
 * CEO审批实现
 */
public class CEOApprover extends Approver {

    @Override
    public void doApproval(int money) {
        if (money <= 20000) {
            System.out.println("CEO::这么点钱用不着审批::交给下一个审批人");
        } else {
            System.out.println("CEO::审批通过::交给下一个审批人");
        }
        this.delivery(money);
    }
}

测试

/**
 * 测试
 */
public class ChainTest {

    public static void main(String[] args) {
        TeamLeaderApprover teamLeaderApprover = new TeamLeaderApprover();
        DeptLeaderApprover deptLeaderApprover = new DeptLeaderApprover();
        CEOApprover ceoApprover = new CEOApprover();

        //给当前审批人设置下一个审批人
        teamLeaderApprover.setNextApprover(deptLeaderApprover);
        deptLeaderApprover.setNextApprover(ceoApprover);

        //执行审批行为,自动传递
        teamLeaderApprover.doApproval(10000);
    }
}

运行结果

TeamLeader::没有权限::交给下一个审批人
DeptLeader::审批通过::交给下一个审批人
CEO::这么点钱用不着审批::交给下一个审批人
结束::没有下一个审批人了

框架源码中的应用

  1. javax.servlet包中的Filter接口

总结

优点

  1. 将请求发送者和接受者解耦
  2. 增加新的请求处理类很方便
  3. 可以灵活的安排链条中每个节点的顺序或删除某一个节点

缺点

  1. 当链条过长时会对系统性能造成一定影响
  2. 不能保证请求一定被接收,因为请求发送过去之后没有反馈
posted @ 2022-08-20 15:13  竹堑  阅读(82)  评论(0编辑  收藏  举报