美文网首页
行为型模式——责任链模式

行为型模式——责任链模式

作者: Doooook | 来源:发表于2020-08-17 21:54 被阅读0次

设想一个场景,需要对一批从客户端来的数据进行多种不同的操作,我们会使用多个不同的类负责不同的操作,而不是使用一个类集成所有操作,这样做能让代码松耦合且简洁。
这些类被称为处理器,第一个处理器会接收请求,如果它需要执行操作则会进行一次调用,如果不需要则会将请求传递给第二个处理器。类似地,第二个处理器确认并将请求传递给责任链中的下一个处理器。

  1. 目的
    责任链模式可以让处理器按以下方式处理:如果需要则处理请求,否则将请求传递给下一个处理器。
  2. 实现
    所示的类图描述了责任链模式的结构和行为:


    image.png

类图中主要包含以下类:

  • Client(客户端):客户端是使用责任链模式的应用程序的主要结构。它的职责是实例化一个处理器的链,然后在第一个对象中调用handleRequest方法。
  • Handler(处理器):这是一个抽象类,提供给所有实际处理器进行继承。它拥有一个handleRequest方法,用来接收需要处理的请求。
  • ConcreteHandler(具体处理器):这是一个实现了handleRequest方法的具体类。每一个具体处理器都维持一个引用,指向链中下一个具体处理器,需要检查它自身是否能处理这个请求,不能就将请求传递给链中的下一个具体处理器。

每一个处理器需要实现一个方法,该方法被客户端所使用,并能够设置下一个处理器,当它无法处理请求时,将请求传给下一个处理器。这个方法可以加入到Handle基类当中。

/**
     * 设置下一节点
     *
     * @param handler
     */
    public void setNextHandler(AbstractLeaveHandler handler) {
        this.nextHandler = handler;
    }

在每一个ConcreteHandler类中,我们实现下列代码,检查它是否能处理请求,不能则会传递请求:


image.png

客户端负责在调用链头之前建立处理器链。这次调用会被传递,直到发现了能正确处理这个请求的处理器。

实例

这里一员工请假为例:
现实中,请假的OA申请,请假天数如果是半天到1天,可能直接主管批准即可;
如果是1到3天的假期,需要部门经理批准;
如果是3天到30天,则需要总经理审批;
大于30天,正常不会批准。

主要类

  • 员工提交请求类:LeaveRequest
  • 抽象的请假责任处理类:AbstractLeaveHandler
  • 直接主管审批处理类:DirectLeaderLeaveHandler
  • 部门经理处理类:DeptManagerLeaveHandler
  • 总经理处理类: GeneralManagerLeaveHandler

实现

员工请求发起申请到抽象的责任处理类中,根据员工的请假天数,对应的处理类完成处理。
每一个责任处理类设置下面的节点。自身处理不了则传递给下一个节点处理。

员工提交请求类LeaveRequest.java

/**
 * @author Jay Mitter
 * @description: 员工提交请求类
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class LeaveRequest {
    /**
     * 天数
     */
    private int leaveDays;
    /**
     * 姓名
     */
    private String name;
}

请假责任链抽象处理类AbstractLeaveHandler.java

/**
 * @author: Jay Mitter
 * @description: 请假责任链抽象处理类
 */
    public abstract class AbstractLeaveHandler {
    /**
     * 直接主管审批处理的请假天数
     */
    protected static final int MIN = 1;
    /**
     * 部门经理处理的请假天数
     */
    protected static final int MIDDLE = 3;
    /**
     * 总经理处理的请假天数
     */
    protected static final int MAX = 30;
    /**
     * 领导名称
     */
    protected String handlerName;
    /**
     * 下一个处理节点(即更高级别的领导)
     */
    protected AbstractLeaveHandler nextHandler;

    /**
     * 设置下一节点
     *
     * @param handler
     */
    public void setNextHandler(AbstractLeaveHandler handler) {
        this.nextHandler = handler;
    }

    /**
     * 处理请假的请求,子类实现
     * @param request
     */
    public abstract void handlerRequest(LeaveRequest request);

}

直接主管处理类DirectLeaderLeaveHandler.java

/**
 * @author: Jay Mitter
 * @description: 直接主管处理类
 */
public class DirectLeaderLeaveHandler extends AbstractLeaveHandler {

    public DirectLeaderLeaveHandler(String name) {
        this.handlerName = name;
    }

    @Override
    public void handlerRequest(LeaveRequest request) {
        if (request.getLeaveDays() <= MIN) {
            System.out.println("直接主管: " + handlerName + ",已经处理;流程结束。");
            return;
        }

        if (null != this.nextHandler) {
            this.nextHandler.handlerRequest(request);
        } else {
            System.out.println("审批拒绝!");
        }
    }
}

部门经理处理类DeptManagerLeaveHandler.java

/**
 * @author: Jay Mitter
 * @description: 部门经理处理类
 */
public class DeptManagerLeaveHandler extends AbstractLeaveHandler {

    public DeptManagerLeaveHandler(String name) {
        this.handlerName = name;
    }

    @Override
    public void handlerRequest(LeaveRequest request) {
        if (request.getLeaveDays() > MIN && request.getLeaveDays() <= MIDDLE) {
            System.out.println("部门经理: " + handlerName + ",已经处理;流程结束。");
            return;
        }

        if (null != this.nextHandler) {
            this.nextHandler.handlerRequest(request);
        } else {
            System.out.println("审批拒绝!");
        }
    }
}

总经理处理类GeneralManagerLeaveHandler.java

/**
 * @author: Jay Mitter
 * @description: 总经理处理类
 */
public class GeneralManagerLeaveHandler extends AbstractLeaveHandler {

    public GeneralManagerLeaveHandler(String name) {
        this.handlerName = name;
    }

    @Override
    public void handlerRequest(LeaveRequest request) {
        if (request.getLeaveDays() > MIDDLE && request.getLeaveDays() <= MAX) {
            System.out.println("总经理: " + handlerName + ",已经处理;流程结束。");
            return;
        }

        if (null != this.nextHandler) {
            this.nextHandler.handlerRequest(request);
        } else {
            System.out.println("审批拒绝!");
        }
    }
}

测试:

    /**
     * 行为型模型——责任链模式
     */
    @Test
    public void testBehaviorDutyChain() {
        LeaveRequest request = LeaveRequest.builder().leaveDays(40).name("小明").build();
        AbstractLeaveHandler directLeaderLeaveHandler = new DirectLeaderLeaveHandler("县令");
        DeptManagerLeaveHandler deptManagerLeaveHandler = new DeptManagerLeaveHandler("知府");
        GeneralManagerLeaveHandler generalManagerLeaveHandler = new GeneralManagerLeaveHandler("京兆尹");

        directLeaderLeaveHandler.setNextHandler(deptManagerLeaveHandler);
        deptManagerLeaveHandler.setNextHandler(generalManagerLeaveHandler);
        directLeaderLeaveHandler.handlerRequest(request);
    }

相关文章

网友评论

      本文标题:行为型模式——责任链模式

      本文链接:https://www.haomeiwen.com/subject/mbmxjktx.html