【java设计模式】之 责任链(chain of resposibility)模式

来源:互联网 发布:淘宝的试用报告怎么写 编辑:程序博客网 时间:2024/05/22 09:09

 责任链模式,顾名思义,就是一条链。这个链到底是怎么运行的呢?它主要是将能够处理同一类请求的对象连成一条链,所提交的请求沿着链传递,链上的对象逐个判断是否有能力处理该请求,如果能则处理,如果不能则传递给链上的下一个对象进行处理,以此类推。 
  比如说公司请假需要审批,举个不恰当的例子,如果请假小于3天,主管审批;3-10天的,经理审批;10-30天的,总经理审批;超过30天的,不批准等等。这就得一步步去判断,如果撇开设计模式不看的话,那么我们可以使用if…else…把它解决了,但是问题可想而知,实际中的复杂程度时远远超过这个例子的。 
  下面使用责任链模式来实现一下这个场景,先来看一下它们之间的关系结构: 
这里写图片描述
  Leader是个抽象类,里面有个方法是获取下一个Leader,Director、Manager和GeneralManager分别继承这个抽象类。LeaveRequest中封装了请假的相关信息。下面来实现一下这个责任链模式。 
首先是封装请假信息的类:

/** * @Description 封装请假的基本信息 * @author Ni Shengwu * */public class LeaveRequest {    private String name;    private int leaveDays;    private String reason;    public LeaveRequest(String name, int leaveDays, String reason) {        super();        this.name = name;        this.leaveDays = leaveDays;        this.reason = reason;    }    //省略get和set方法}   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

然后就是定义Leader这个抽象类了

/** * @Description 领导的抽象类 * @author Ni Shengwu * */public abstract class Leader {    protected String name;    protected Leader nextLeader; //责任链上的后继对象,即这个对象无法处理,就转移给下一个Leader    public Leader(String name) {        super();        this.name = name;    }    // 设定责任链上的后继对象    public void setNextLeader(Leader nextLeader) {        this.nextLeader = nextLeader;    }    /**     * 处理请求的核心的业务方法     * 需要不同继承该类的领导自己实现     */    public abstract void handleRequest(LeaveRequest request);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

主管、经理和总经理都需要继承该类,并实现处理请假的这个方法。

/** * @Description 主任 * @author Ni Shengwu * */public class Director extends Leader {    public Director(String name) {        super(name);    }    @Override    public void handleRequest(LeaveRequest request) {        int days = request.getLeaveDays(); //获取请假天数        String name = request.getName(); //获取请假人姓名        String reason = request.getReason(); // 获取请假理由        if(days <= 3) { //如果满足3天内的要求,主任直接审批            System.out.println("员工" + name + "请假" + days + "天,理由:" + reason);            System.out.println("主任" + this.name + "审批通过");        } else {            System.out.println("请假天数过多,主任" + this.name + "没法处理");            if(this.nextLeader != null) { //否则,如果链上存在下一个Leader,就让他处理                this.nextLeader.handleRequest(request);            }         }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
/** * @Description 经理 * @author Ni Shengwu * */public class Manager extends Leader {    public Manager(String name) {        super(name);    }    @Override    public void handleRequest(LeaveRequest request) {        int days = request.getLeaveDays(); //获取请假天数        String name = request.getName(); //获取请假人姓名        String reason = request.getReason(); // 获取请假理由        if(days <= 10) { //如果满足10天内的要求,经理直接审批            System.out.println("员工" + name + "请假" + days + "天,理由:" + reason);            System.out.println("经理" + this.name + "审批通过");        } else {            System.out.println("请假天数过多,经理" + this.name + "没法处理");            if(this.nextLeader != null) { //否则,如果链上存在下一个Leader,就让他处理                this.nextLeader.handleRequest(request);            }         }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
/** * @Description 总经理 * @author Ni Shengwu * */public class GeneralManager extends Leader {    public GeneralManager(String name) {        super(name);    }    @Override    public void handleRequest(LeaveRequest request) {        int days = request.getLeaveDays(); //获取请假天数        String name = request.getName(); //获取请假人姓名        String reason = request.getReason(); // 获取请假理由        if(days <= 30) { //如果满足30天内的要求,总经理直接审批            System.out.println("员工" + name + "请假" + days + "天,理由:" + reason);            System.out.println("总经理" + this.name + "审批通过");        } else {            System.out.println("请假天数过多,总经理" + this.name + "没法处理");            if(this.nextLeader != null) { //否则,如果链上存在下一个Leader,就让他处理                this.nextLeader.handleRequest(request);            } else {                System.out.println("请假不成功");            }        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

  由此可见,他们处理请求的条件是不同的,而且只要不是自己处理范围之内的,就会将请求传给链上的下一位来处理。接下来写个客户端模拟下:

public class Client {    public static void main(String[] args) {        Leader director = new Director("张三");        Leader manager = new Manager("李四");        Leader gManager = new GeneralManager("王五");        // 组织好责任链对象的关系        director.setNextLeader(manager);        manager.setNextLeader(gManager);        // 开始请假操作        LeaveRequest request = new LeaveRequest("倪升武", 15, "在家睡觉");        director.handleRequest(request);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

运行结果:

请假天数过多,主任张三没法处理 
请假天数过多,经理李四没法处理 
员工倪升武请假15天,理由:在家睡觉 
总经理王五审批通过

  在实际中,设置这个链可以放到配置文件中,可以直接修改配置文件即可,这个责任链模式扩展性也很好,比如现在有个副经理,专门处理10-20天的请假,那么我只要新添加一个副经理类即可,然后在责任链上配置一下就行了,对其他的类没有影响。 
  责任链模式使用的地方很多,比如我们常见的try…catch…就是,可以有多个catch,一个个往下判断;再比如servlet里面的过滤器,就是一个责任链;再比如struts2中的拦截器,也是使用的责任链模式。 
  


—–乐于分享,共同进步! 
—–我的博客主页:http://blog.csdn.net/eson_15

阅读全文
0 0
原创粉丝点击