12、责任链模式(设计模式笔记)

#一、概述

  • 设计模式
    • 创建型模式:关注对象的创建过程
    • 结构型模式:关注对象和类的组织
    • 行为型模式:关注系统中对象之间的相互交互,研究系统在运行时对象之间的相互通信和协作,进一步明确对象的责任,共11种模式
  • 责任链模式(chain of responsibility
    定义:将能够处理同一类请求的对象练成一条链,所提交的请求沿着链传递,链上的对象逐个判断是否有能力处理该请求,如果能则处理,否则,传递给链上的下一个对象。

  • 场景:

    • 打牌时,轮流出牌
    • 接力赛跑
    • 大学中,奖学金审批
    • 公司中,公文审批

二、实例:请假条审批流程案例

LeaveRequest.java

package cn.itcast.day243.chainOfRespon;
//请假条:封装请求的基本信息
public class LeaveRequest {
    private String empName;// 请假人
    private int leaveDays;// 请假天数
    private String reason;// 请假原因

    public LeaveRequest() {
    }

    public LeaveRequest(String empName, int 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 int getLeaveDays() {
        return leaveDays;
    }

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

    public String getReason() {
        return reason;
    }

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

说明:这就相当于一个任务类。

Leader.java

package cn.itcast.day243.chainOfRespon;
//审批人:抽象类
public abstract class Leader {
    // 因为只是给子类使用,所以这里使用protected
    protected String name;// 领导名字
    protected Leader nextLeader;// 领导的上一级领导

    public Leader() {
    }

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

    public void setNextLeader(Leader nextLeader) {
        this.nextLeader = nextLeader;
    }
    
    public abstract void handleRequest(LeaveRequest request);//处理请求业务的核心方法
    
}

说明:这是一个处理器接口,因为每个审批对象有很多类似的地方。

Director.java

package cn.itcast.day243.chainOfRespon;
//主任
public class Director extends Leader {

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

    public void handleRequest(LeaveRequest request) {
        if (request.getLeaveDays() < 3) {
            System.out.println("主任处理员工" + request.getEmpName() + "请假"
                    + request.getLeaveDays() + "天,理由是:" + request.getReason());
            System.out.println("主任" + this.name + "审批通过");
        } else {
            if (this.nextLeader != null) {
                this.nextLeader.handleRequest(request);
            }
        }
    }
}

Manager.java

package cn.itcast.day243.chainOfRespon;
//经理
public class Manager extends Leader {

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

    public void handleRequest(LeaveRequest request) {
        if (request.getLeaveDays() < 10) {
            System.out.println("经理处理员工" + request.getEmpName() + "请假"
                    + request.getLeaveDays() + "天,理由是:" + request.getReason());
            System.out.println("经理" + this.name + "审批通过");
        } else {
            if (this.nextLeader != null) {
                this.nextLeader.handleRequest(request);
            }
        }
    }
}

GeneralManager.java

package cn.itcast.day243.chainOfRespon;
//总经理
public class GeneralManager extends Leader {

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

    public void handleRequest(LeaveRequest request) {
        if (request.getLeaveDays() < 30) {
            System.out.println("总经理处理员工" + request.getEmpName() + "请假"
                    + request.getLeaveDays() + "天,理由是:" + request.getReason());
            System.out.println("总经理" + this.name + "审批通过");
        } else {
            System.out.println("总经理处理员工" + request.getEmpName() + "请假"
                    + request.getLeaveDays() + "天,理由是:" + request.getReason());
            System.out.println("总经理" + this.name + "审批不通过");
        }
    }
}

说明:这是三个具体的处理器,分别处理不同等级但同类的事件。

Client.java

package cn.itcast.day243.chainOfRespon;
public class Client {
    public static void main(String[] args) {
        Leader l1 = new Director("张三");
        Leader l2 = new Manager("李四");
        Leader l3 = new GeneralManager("王五");
        
        //组织责任链对象的关系
        l1.setNextLeader(l2);
        l2.setNextLeader(l3);
        
        //处理请假操作
        LeaveRequest request = new LeaveRequest("Tom", 1, "回英国老家探亲");
        l1.handleRequest(request);
    }
}

说明:可以看到各个具体的处理器的关系是我们在使用的时候才确定的,如果我们需要在中间添加其他的处理器类可以很方便的添加,只需要在使用的时候调整各个处理器的关系即可。

三、两种责任链方式

  • 链表方式定义职责链(上面的案例)
  • 非链表方式实现职责链
    通过集合、数组生成职责链更加使用。实际上,很多项目中,每个具体Handler并不是由开发团队定义的,而是项目上线后由外部单位追加的,所以使用链表方式定义COR链就很困难。

四、开发中常见的场景

  • java中,异常机制就是一种责任链模式。一个try可以对应多个catch,当第一个catch不匹配类型,则自动跳到第二个catch
  • js中,事件的冒泡和捕获机制。java中,事件处理采用观察者模式
  • servlet中,过滤器的链式处理
  • struts2中,拦截器的调用也是典型的责任链模式
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1 场景问题# 1.1 申请聚餐费用## 来考虑这样一个功能:申请聚餐费用的管理。 很多公司都有这样的福利,就是项...
    七寸知架构阅读 3,169评论 3 58
  • 一、设计模式的分类 总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者...
    RamboLI阅读 768评论 0 1
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,739评论 18 399
  • http://jafeney.com/2016/03/06/20160306-gulp/
    forwardRain阅读 196评论 0 0
  • 田生万物成长日记第十九天 微信号:zspgy168 今天的主题让写写父母,可是我却不知道如何下笔。 作为远在外地的...
    紫色蒲公英168阅读 199评论 1 0