责任链模式

一、基础学习

  • 定义:所谓的责任链模式就是:将要执行的逻辑形成一条链,在该链上根据链条节点的先后顺序实现任务的处理。
  • 主要解决的问题:作为消息的申请者与消息的处理者都不需要额外关心其他的逻辑,消息的申请者将消息发送到职责链上,消息的处理者只需要对该消息进行接收处理即可,所以该责任链模式实现了解耦的目的。
  • 常见场景:学校审批流程、学生请假、奖学金的申请流程、框架中的过滤器、拦截器。
  • 主要意图:避免消息的发送者与处理者的耦合,可以实现消息让多个处理者接收,将这些多个处理者形成一条链并且沿着这条链处理请求,知道将该请求处理完成。
  • 优点:降低耦合度;简化了对象的处理流程;符合开闭原则,在添加额外的角色的时候,只需要创建器实体类,再将其添加到责任链中即可;指派任务很灵活。
  • 缺点:对于系统的性能可能会受到影响,毕竟有多少个角色就要有多少个实体类,还要创建对象之间的责任处理关系;对于复杂的系统而言,可能会造成对象的循环调用
  • 模式流程图(以请假为例)
  • 项目实现代码:
1、LeaveRequest请假请求类
/**
 * @Description: 请假信息
 * @Author: huidou 惠豆
 * @CreateTime: 2022/6/17 20:19
 */
public class LeaveRequest {

    // 请假人名称
    private String empName;
    // 请假人天数
    private Integer leaveDays;
    // 请假人原因
    private String reason;

    public LeaveRequest(String empName, Integer leaveDays, String reason) {
        this.empName = empName;
        this.leaveDays = leaveDays;
        this.reason = reason;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public Integer getLeaveDays() {
        return leaveDays;
    }

    public void setLeaveDays(Integer leaveDays) {
        this.leaveDays = leaveDays;
    }

    public String getReason() {
        return reason;
    }

    public void setReason(String reason) {
        this.reason = reason;
    }

    @Override
    public String toString() {
        return "LeaveRequest{" +
                "empName='" + empName + '\'' +
                ", leaveDays=" + leaveDays +
                ", reason='" + reason + '\'' +
                '}';
    }
}
2、Leader抽象类
/**
 * @Description: 抽象类(Leader)
 * @Author: huidou 惠豆
 * @CreateTime: 2022/6/17 20:03
 */
public abstract class Leader {

    // 领导名称
    protected String name;
    // 下一个领导
    protected Leader nextLeader;

    public Leader(String name) {
        super();
        this.name = name;
    }

    // 设置责任链上下一个处理对象
    public void setNextLeader(Leader leader) {
        this.nextLeader = leader;
    }

    // 处理请求的方法
    public abstract void handlerRequest(LeaveRequest leaveRequest);

}
3、Director主任类
/**
 * @Description: 主任处理类
 * @Author: huidou 惠豆
 * @CreateTime: 2022/6/17 20:21
 */
public class Director extends Leader {


    public Director(String name) {
        super(name);
    }

    /**
     * 请求处理
     * 权力:对于请假天数是 1~3天
     * @param leaveRequest
     */
    @Override
    public void handlerRequest(LeaveRequest leaveRequest) {
        if (leaveRequest.getLeaveDays() <= 3) {
            System.out.println("员工姓名:" + leaveRequest.getEmpName() + "请假天数:" + leaveRequest.getLeaveDays() + " 原因是:" + leaveRequest.getReason());
            System.out.println("主任: "+ this.name + " 审批通过");
        } else {
            // 判断我的下一个处理对象是否为null
            if (this.nextLeader != null) {
                this.nextLeader.handlerRequest(leaveRequest);
            }
        }
    }
}
4、Manager经理类
/**
 * @Description: 经理处理类
 * @Author: huidou 惠豆
 * @CreateTime: 2022/6/17 20:27
 */
public class Manager extends Leader{

    public Manager(String name) {
        super(name);
    }

    /**
     * 请求处理
     * 权力:对于请假天数是 4~15天
     * @param leaveRequest
     */
    @Override
    public void handlerRequest(LeaveRequest leaveRequest) {
        if (leaveRequest.getLeaveDays() > 3 && leaveRequest.getLeaveDays() <= 15) {
            System.out.println("员工姓名:" + leaveRequest.getEmpName() + "请假天数:" + leaveRequest.getLeaveDays() + " 原因是:" + leaveRequest.getReason());
            System.out.println("经理: "+ this.name + " 审批通过");
        } else {
            // 判断我的下一个处理对象是否为null
            if (this.nextLeader != null) {
                this.nextLeader.handlerRequest(leaveRequest);
            }
        }
    }
}
5、GeneralManager总经理类
/**
 * @Description: 总经理处理类
 * @Author: huidou 惠豆
 * @CreateTime: 2022/6/17 20:28
 */
public class GeneralManager extends Leader{

    public GeneralManager(String name) {
        super(name);
    }

    /**
     * 请求处理
     * 权力:对于请假天数是 16~30天
     * @param leaveRequest
     */
    @Override
    public void handlerRequest(LeaveRequest leaveRequest) {
        if (leaveRequest.getLeaveDays() > 16 && leaveRequest.getLeaveDays() <= 30) {
            System.out.println("员工姓名:" + leaveRequest.getEmpName() + "请假天数:" + leaveRequest.getLeaveDays() + " 原因是:" + leaveRequest.getReason());
            System.out.println("总经理: "+ this.name + " 审批通过");
        } else {
            // 判断我的下一个处理对象是否为null
            if (this.nextLeader != null) {
                this.nextLeader.handlerRequest(leaveRequest);
            } else {
                System.out.println("莫非" + leaveRequest.getEmpName() + "想要辞职,请假天数: " + leaveRequest.getLeaveDays());
            }
        }
    }
}
6、Client客户端类
/**
 * @Description: 客户端请求
 * @Author: huidou 惠豆
 * @CreateTime: 2022/6/17 20:32
 */
public class Client {
    public static void main(String[] args) {
        // 实例化领导对象
        Leader direct = new Director("张三");
        Leader manager = new Manager("李四");
        Leader generalManager = new GeneralManager("王五");
        // 设置处理流程
        direct.setNextLeader(manager);
        manager.setNextLeader(generalManager);
        // 发送请求
        LeaveRequest leaveRequest = new LeaveRequest("小明",222,"回家");
        direct.handlerRequest(leaveRequest);
    }
}
  • 执行结果测试:
  • 对于请假1~3天

  • 对于请假4~15天

  • 对于请假16~30天

  • 对于请假超过30天



 二、进阶练习

  • 需求:小王有三门课程,分别是:语文、数学、英语,他不好好学习,结果全部的课程都需要重修,而且需要老师的同意才可以继续学习,为了避免线下工作,使用责任链模式思想实现一个在线申请。
  • 项目技术选型:

























全部评论

相关推荐

11-06 10:58
已编辑
门头沟学院 嵌入式工程师
双非25想找富婆不想打工:哦,这该死的伦敦腔,我敢打赌,你简直是个天才,如果我有offer的话,我一定用offer狠狠的打在你的脸上
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务