责任链设计模式

概念

责任链(chain of responsibility)模式很像异常的捕获和处理,当一个问题发生的时候,当前对象看一下自己是否能够处理,不能的话将问题抛给自己的上级去处理,但是要注意这里的上级不一定指的是继承关系的父类,这点和异常的处理是不一样的。所以可以这样说,当问题不能解决的时候,将问题交给另一个对象去处理,就这样一直传递下去直至当前对象找不到下线了,处理结束。如下图所示,处于同等层次的类都继承自LeaveProcess类,当当前对象不能处理的时候,会根据预先设定好的传递关系将问题交给下一个人,可以说是“近水楼台先得月”,就看有没有能力了。我们也可以看作是大家在玩一个传谜语猜谜底的小游戏,按照座位的次序以及规定的顺序传递,如果一个人能回答的上来游戏就结束,否则继续向下传,如果所有人都回答不出来也会结束。这样或许才是责任链的本质,体现出了同等级的概念。

场景

请假模型:请假条先递交给组长,组长只有处理两天请假权限,如果超出递交给部门领导处理,部门领导只有处理五天的权限,超出权限递交给公司领导处理

利用责任链设计模式实现

假条模型

public class LeaveRequisition {
    private String name;
    private String deptName;
    private Integer days;

    public LeaveRequisition(String name, String deptName, Integer days) {
        this.name = name;
        this.deptName = deptName;
        this.days = days;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDeptName() {
        return deptName;
    }

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }

    public Integer getDays() {
        return days;
    }

    public void setDays(Integer days) {
        this.days = days;
    }
}

请假处理器接口

public interface LeaveProcess {
    void process(LeaveRequisition leaveRequisition);
}

各种请假处理器实现

小组领导
public class GroupLeaderProcess implements LeaveProcess {
    private LeaveProcess nextProcess;

    public GroupLeaderProcess() {
    }

    public GroupLeaderProcess(LeaveProcess nextProcess) {
        this.nextProcess = nextProcess;
    }

    public void process(LeaveRequisition leaveRequisition) {
        if (leaveRequisition.getDays()> 2){
            System.out.println("小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批");
            nextProcess.process(leaveRequisition);
            return;
        }
        System.out.println("请假批准,"+leaveRequisition.getDays()+"后快去快回");
    }
}

部门领导
public class DepartmentLeader implements LeaveProcess {
    private LeaveProcess nextProcess;

    public DepartmentLeader() {
    }

    public DepartmentLeader(LeaveProcess nextProcess) {
        this.nextProcess = nextProcess;
    }

    public void process(LeaveRequisition leaveRequisition) {
        if (leaveRequisition.getDays()> 5){
            System.out.println("部门经理只有审批五天的请假权限,该申请超过五天,移交给公司领导审批");
            nextProcess.process(leaveRequisition);
            return;
        }
        System.out.println("请假批准,"+leaveRequisition.getDays()+"后快去快回");
    }
}

公司领导
public class CompanyProcess implements LeaveProcess {

    private LeaveProcess nextProcess;

    public CompanyProcess() {
    }

    public CompanyProcess(LeaveProcess nextProcess) {
        this.nextProcess = nextProcess;
    }

    public void process(LeaveRequisition leaveRequisition) {
        System.out.println("请假批准,"+leaveRequisition.getDays()+"后快去快回");
    }
}

测试类

public class TestProcess {
    public static void main(String[] args) {
        // 创建请假条
        LeaveRequisition leaveRequisition = new LeaveRequisition("zhansan", "dev", 9);

        // 构建责任链
        LeaveProcess leaveProcess = new GroupLeaderProcess(new DepartmentLeader(new CompanyProcess()));

        // 提交请假申请
        leaveProcess.process(leaveRequisition);
    }
}

运行结果

小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批
部门经理只有审批五天的请假权限,该申请超过五天,移交给公司领导审批
请假批准,9后快去快回

责任链设计模式优化

该模式存在一个问题,当业务的吞吐量很大的时候,每次移交必须等到下一级别的返回才算结束,其实在我们提交申请之后是不关心请假到底是否被批准,只是过会过来看一下结果就好,所以我们就可以采用一个阻塞 队列,每次提交i只是放到下一级审批人的阻塞队列中,审批人自己 去取就好了,这就是一个典型的生产者消费这模式,java回我们提供了很多阻塞队列,我们就可以基于这种思想去对这个请假的责任链进行优化

优化代码如下

private LeaveProcess nextProcess;
    
    // 存放请假消息
    private LinkedBlockingQueue<LeaveRequisition> leaveRequisitions = new LinkedBlockingQueue<LeaveRequisition>();
    
    // 用判断是否结束
    private boolean isFinish = false;

    public GroupLeaderProcess() {
    }

    public GroupLeaderProcess(LeaveProcess nextProcess) {
        this.nextProcess = nextProcess;
    }

    @Override
    public void run() {
        while (!isFinish){
            try {
                // 消费者
                LeaveRequisition leaveRequisition = leaveRequisitions.take();
                if (leaveRequisition.getDays()> 2){
                    System.out.println("小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批");
                    nextProcess.process(leaveRequisition);
                    continue;
                }
                System.out.println("请假批准,"+leaveRequisition.getDays()+"后快去快回");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    // 生产者
    public void process(LeaveRequisition leaveRequisition) {
        leaveRequisitions.add(leaveRequisition);
    }
}

这里只贴出小组处理,其他的也一样

测试

public class TestProcess {
    public static void main(String[] args) {
        CompanyProcess companyProcess = new CompanyProcess();
        companyProcess.start();
        DepartmentLeader departmentLeader = new DepartmentLeader(companyProcess);
        departmentLeader.start();
        // 构建责任链
        GroupLeaderProcess groupLeaderProcess = new GroupLeaderProcess(departmentLeader);
        groupLeaderProcess.start();
        // 提交请假申请
        for (int i = 0; i < 10; i++) {
            // 创建请假条
            LeaveRequisition leaveRequisition = new LeaveRequisition("zhansan", "dev", i);
            groupLeaderProcess.process(leaveRequisition);
        }
    }
}

测试结果

请假批准,0后快去快回
请假批准,1后快去快回
请假批准,2后快去快回
小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批
小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批
小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批
小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批
请假批准,3后快去快回
请假批准,4后快去快回
请假批准,5后快去快回
小组主管只有审批五天的请假权限,该申请超过五天,移交给公司经理审批
小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批
小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批
小组主管只有审批两天的请假权限,该申请超过两天,移交给部门经理审批
小组主管只有审批五天的请假权限,该申请超过五天,移交给公司经理审批
小组主管只有审批五天的请假权限,该申请超过五天,移交给公司经理审批
小组主管只有审批五天的请假权限,该申请超过五天,移交给公司经理审批
请假批准,6后快去快回
请假批准,7后快去快回
请假批准,8后快去快回
请假批准,9后快去快回

结束语

有何不对谢谢指正,走在BAT的路上,我们一起进步

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值