目录

说明

实现方式

优点

缺点

应用场景

说明

  • 行为型模式之一,其他还有命令模式、模板方法模式、访问者模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、迭代器模式
  • 职责链模式(Chain of Responsibility Pattern), 又叫责任链模式,为请求创建了一个 接收者对象的链(简单示意图)。这种模式对请求的发送者和接收者进行解耦
  • 职责链模式通常 每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推

实现方式

“老板,我想加薪。”

“没问题,我先问问老总。”

“。。。”

“老板,我想请假。”

“没问题,批了。”

“啊这”

java责任链模式案例 java职责链模式_职责链

 

/**
 * 职责链模式(使多个对象都有机会处理请求。将对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止)
 *
 * @author ZRH
 * @version 1.0.0
 * @date 2020/7/23
 */
public class ChainOfResponsibilityTest {
    public static void main(String[] args) {
        Manager commonManger = new CommonManger("普通经理小明");
        Manager generalManager = new GeneralManager("总经理王总");
        // 设置上级关系
        commonManger.setSuperior(generalManager);

        Request askForLeaveRequest = new Request();
        askForLeaveRequest.setRequestType("请假");
        askForLeaveRequest.setRequestContent("程序员小红申请请假一天");
        // 申请由普通经理发起,但具体谁决策,客户端并不知道
        commonManger.requestApplication(askForLeaveRequest);

        Request raiseRequest = new Request();
        raiseRequest.setRequestType("加薪");
        raiseRequest.setRequestContent("程序员小刚申请加薪500");
        commonManger.requestApplication(raiseRequest);
    }
}

/**
 * 抽象的管理者类(Handler)
 * <p>
 *
 * @author : ZRH
 * @version : 1.0.0
 * @date : 2020-07-24
 */
abstract class Manager {
    private String name;

    public Manager(String name) {
        this.name = name;
    }

    /**
     * 上级
     */
    private Manager superior;

    /**
     * 处理请求
     * <p>
     *
     * @param request
     * @author : ZRH
     * @version : 1.0.0
     * @date : 2020-07-23
     */
    public abstract void requestApplication(Request request);

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Manager getSuperior() {
        return superior;
    }

    public void setSuperior(Manager superior) {
        this.superior = superior;
    }
}

/**
 * 普通经理(ConcreteHandler1)
 * <p>
 *
 * @author ZRH
 * @version 1.0.0
 * @date 2020/7/24
 */
class CommonManger extends Manager {
    private static String ASK_FOR_LEAVE = "请假";

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

    /**
     * 处理请求
     * <p>
     *
     * @param request
     * @author : ZRH
     * @version : 1.0.0
     * @date : 2020-07-23
     */
    @Override
    public void requestApplication(Request request) {
        if (ASK_FOR_LEAVE.equals(request.getRequestType())) {
            System.out.println(getName() + "批准" + request.getRequestContent());
        } else {
            if (getSuperior() != null) {
                // 其余的申请交由上级处理
                getSuperior().requestApplication(request);
            }
        }
    }
}

/**
 * 总经理(ConcreteHandler2)
 * <p>
 *
 * @author ZRH
 * @version 1.0.0
 * @date 2020/7/24
 */
class GeneralManager extends Manager {
    private static String RAISE = "加薪";

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

    /**
     * 处理请求
     * <p>
     *
     * @param request
     * @author : ZRH
     * @version : 1.0.0
     * @date : 2020-07-23
     */
    @Override
    public void requestApplication(Request request) {
        if (RAISE.equals(request.getRequestType())) {
            System.out.println(getName() + "批准" + request.getRequestContent());
        } else {
            System.out.println(request.getRequestType() + "要再考虑");
        }
    }
}

/**
 * 申请
 * <p>
 *
 * @author ZRH
 * @version 1.0.0
 * @date 2020/7/24
 */
class Request {
    /**
     * 申请的类型
     */
    private String requestType;
    /**
     * 申请的内容
     */
    private String requestContent;

    public String getRequestType() {
        return requestType;
    }

    public void setRequestType(String requestType) {
        this.requestType = requestType;
    }

    public String getRequestContent() {
        return requestContent;
    }

    public void setRequestContent(String requestContent) {
        this.requestContent = requestContent;
    }
}

优点

  • 将请求和处理分开,实现解耦,提高系统的灵活性
  • 简化了对象,使对象不需要知道链的结构

缺点

  • 性能会受到影响,特别是在链比较长的时候,因此需控制链中最大节点数量,一般通过在Handler中设置一个最大节点数量,在setNext()方法中判断是否已经超过阀值,超过则不允许该链建立,避免出现超长链无意识地破坏系统性能
  • 调试不方便。采用了类似递归的方式,调试时逻辑可能比较复杂

应用场景

  • 多级请求
  • 请假 / 加薪等审批流程
  • Java Web 中 Tomcat 对 Encoding 的处理
  • 拦截器