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

2020-08-17  本文已影响0人  Doooook

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

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


    image.png

类图中主要包含以下类:

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

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

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


image.png

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

实例

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

主要类

实现

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

员工提交请求类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);
    }
上一篇 下一篇

猜你喜欢

热点阅读