Java设计模式12——责任链模式

一、定义


  将能够处理同一类请求的对象连成一条链,所提交的请求将沿着这条链传递,链上的对象逐个判断是否有能力处理该请求,如果有则处理,如果没有则将请求传递给下一个对象处理。

二、场景举例


1.生活中场景
在学校时,请假条的审批过程:

  • 如果请假小于3天,辅导员直接批准。
  • 如果请假大于等于3天小于10天,需院长审批。
  • 如果请假大于等于10天小于30天,校长审批。
  • 请假被拒绝

2.开发中场景
  Java中,异常机制就是一种责任链模式。一个try可以对应多个catch,当第一个catch不匹配时,则自动跳到第二个catch。

上述就是一个责任链,各级对象都有处理请求能力但处理能力不同,请求一直沿着责任链传递下去。

三、模式结构


  • Requester请求者:请求类。
  • AbstractHandler抽象处理者:由于各级对象都具有相同的处理能力,所以有一个公共的抽象父接口。
  • ConcreteHandler具体处理者:具有不同处理能力的处理类。

代码示例:
Requester请求者:

/**
 * 请求者发出请假:学生类
 */
public class Student {
    private String name;
    private int leaveDays;
    private String reason;
    public Student(String name, int leaveDays, String reason) {
        super();
        this.name = name;
        this.leaveDays = leaveDays;
        this.reason = reason;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getLeaveDays() {
        return leaveDays;
    }
    public void setLeaveDays(int leaveDays) {
        this.leaveDays = leaveDays;
    }



}

AbstractHandler抽象处理者:

/**
 * 抽象处理者:领导类
 */
public abstract class Leader {
    protected String name;
    protected Leader nextHandler;//责任链上的后继对象
    public Leader(String name) {
        super();
        this.name = name;
    }

    //设定责任链上的后继对象
    public void setNextHandler(Leader nextHandler) {
        this.nextHandler = nextHandler;
    }

    // 处理请求的核心的业务方法
    protected abstract void handleRequest(Student student);


}

ConcreteHandler抽象处理者:

/**
 * 具体处理者:辅导员类
 */
public class Assistant extends Leader {

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

    @Override
    protected void handleRequest(Student student) {
        if(student.getLeaveDays()<3){
            System.out.println("辅导员:"+this.name+"批准"+student.getName()+"的请假");
        }else{
            if(this.nextHandler!=null){
                this.nextHandler.handleRequest(student);
            }
        }
    }
}



/**
 * 具体处理者:院长类
 */
public class Dean extends Leader {

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

    @Override
    protected void handleRequest(Student student) {
        if(student.getLeaveDays()<10){
            System.out.println("院长:"+this.name+"批准"+student.getName()+"的请假");
        }else{
            if(this.nextHandler!=null){
                this.nextHandler.handleRequest(student);
            }       
        }
    }
}

/**
 * 具体处理者:校长类
 */
public class HeadMaster extends Leader {

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

    @Override
    protected void handleRequest(Student student) {
        if(student.getLeaveDays()<30){
            System.out.println("校长:"+this.name+"批准"+student.getName()+"的请假");
        }else{
            System.out.println("请假被拒绝");    
        }
    }
}

客户端:

public class Client {

    public static void main(String[] args) {
        Leader assistant=new Assistant("张三");
        Leader dean=new Dean("李四");
        Leader headMaster=new HeadMaster("王五");
        //组织责任链对象的关系
        assistant.setNextHandler(dean);
        dean.setNextHandler(headMaster);

        //开始请假操作
        Student student=new Student("赵六",15,"回家探亲");
        assistant.handleRequest(student);
    }
}

UML类图:
这里写图片描述

四、非链表实现责任链


上述代码通过链表的方式定义责任链,而往往通过集合、数组生成责任链更加实用。实际上,在很多项目中,每个具体的Handler并不是由开发团队定义的,而是项目上线后由外部单位追加的,所以使用链表方式定义COR链就很困难。

五、总结


  • 使用场景要求:
    • 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定;
    • 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求;
    • 处理一个请求的对象集合应被动态指定。
  • 缺点:
    • 对于每一个请求都需要遍历职责链,性能是个问题。

职责链模式对于请求的处理是不知道最终处理者是谁,所以是运行动态寻找并指定;而命令模式中对于命令的处理时在创建命令是已经显式或隐式绑定了接收者。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值