设计模式-行为型-责任链模式

责任链模式(职责链模式)

描述

  • 比如生活中,学生要请假,如果请假三两天,老师即可,如果要请假三两周,就要去找教导主任,如果要请假一年,就要去找校长。这样学生必须记住每个领导的电话联系方式等。难度增加。
  • 为了避免请求者(学生)与多个处理者(领导们)耦合,将所有处理者通过前一个对象记住下一个对象的引用,连成一条线(责任链模式)。

角色

  • 抽象处理者角色:处理规范,且定义了后续连接。
  • 具体处理者角色:实现抽象处理者,判断本次请求是否处理,是否要交给后续连接
  • 客户角色:创建处理者,并向处理者提交请求。不关心具体处理细节。

实现

public class Test {
    public static void main(String[] args) {
        StudentRequest studentRequest = new StudentRequest("小明", 60, "参加奥运会");
        // 各级处理者
        TeacherHandler teacherHandler = new TeacherHandler();
        DirectorHandler directorHandler = new DirectorHandler();
        PrincipalHandler principalHandler = new PrincipalHandler();
        // 设置处理者链
        teacherHandler.setNextHandler(directorHandler);
        directorHandler.setNextHandler(principalHandler);
        // 提交申请
        teacherHandler.submit(studentRequest);
    }
}
// 请求
class StudentRequest {
    private String name;
    private Integer number;
    private String content;

    public String getName() {
        return name;
    }

    public Integer getNumber() {
        return number;
    }

    public String getContent() {
        return content;
    }

    StudentRequest(String name, Integer number, String content) {
        this.name = name;
        this.number = number;
        this.content = content;
    }
}

// 抽象处理者角色
abstract class Handler {

    public static final Integer GRADE_ONE = 7;
    public static final Integer GRADE_TWO = 30;
    public static final Integer GRADE_THREE = 365;
    // 请假天数
    private Integer numberStart;
    private Integer numberEnd;

    // 后继处理者
    private Handler nextHandler;

    Handler(Integer number) {
        this.numberStart = number;
    }
    Handler(Integer numberStart, Integer numberEnd) {
        this.numberStart = numberStart;
        this.numberEnd = numberEnd;
    }

    // 设置上一级领导
    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

    // 当前处理方式
    public abstract void dealWith(StudentRequest request);

    // 提交处理
    public final void submit(StudentRequest request) {
        if (request.getNumber() >= this.numberStart && request.getNumber() <= this.numberEnd) {
            this.dealWith(request);
        }else if (this.nextHandler != null && request.getNumber() > this.numberEnd) {
            this.nextHandler.submit(request);
        } else {
            System.out.println("审批失败,流程结束");
        }
    }
}
// 教师处理者类 具体处理者类
class TeacherHandler extends Handler{

    TeacherHandler() {
        // 可处理天数
        super(0, GRADE_ONE);
    }

    @Override
    public void dealWith(StudentRequest request) {
        System.out.println(String.format("请假人:%s,请假天数:%d,请假原因:%s", request.getName(), request.getNumber(), request.getContent()));
        System.out.println("老师审批通过");
    }
}
// 主管处理者类 具体处理者类
class DirectorHandler extends Handler{

    DirectorHandler() {
        // 可处理天数
        super(0, GRADE_TWO);
    }

    @Override
    public void dealWith(StudentRequest request) {
        System.out.println(String.format("请假人:%s,请假天数:%d,请假原因:%s", request.getName(), request.getNumber(), request.getContent()));
        System.out.println("主管审批通过");
    }
}
// 校长处理者类 具体处理者类
class PrincipalHandler extends Handler{

    PrincipalHandler() {
        // 可处理天数
        super(0, GRADE_THREE);
    }

    @Override
    public void dealWith(StudentRequest request) {
        System.out.println(String.format("请假人:%s,请假天数:%d,请假原因:%s", request.getName(), request.getNumber(), request.getContent()));
        System.out.println("校长审批通过");
    }
}

优点

  • 降低请求发送者和处理者之间耦合度。
  • 高扩展,可以插拔式的添加或修改或删除某个处理节点,不影响其它节点,满足开闭原则。
  • 一个类只需要维护下一个节点的引用,减少if else if判断。
  • 明确各个节点的职责,符合单一职责原则。

缺点

  • 无法保证每个请求一定被处理,可能到责任链的末尾都无法处理(比如例子中的请假2年)。
  • 责任链过长,系统性能有一定的影响。
  • 责任链建立的合理性,需要由客户端来保证,增加了客户端的复杂度,设置错误可能会导致死循环。

JAVA中的例子

  • Servlet中的Filter链。执行chain.doFilter()才能到下一个请求。
public class TenantFilter implements Filter {
 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
 		
            System.out.println("前处理");
			chain.doFilter(httpServletRequest, response);
            System.out.println("后处理");
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值