设计模式 —— 责任链模式

简介

责任链模式(Chain of Responsibility Pattern)使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。

实例

责任链模式包含一下角色:

  1. Handler: 抽象处理者。定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。
  2. ConcreteHandler:具体处理者。具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
  3. Client:客户类

下面我们以一个简单的请假作为示例。假设请假一天,项目经理处理就能处理,三天之类归项目总监处理,七天内归老板处理,请假不允许超过七天。 抽象处理者

public abstract class AbstractHandler {
    /**
     * 下一个处理对象
     */
    private AbstractHandler next;
    /**
     * 处理请假
     *
     * @param leaveDays 天数
     * @return 处理结果
     */
    public final String handleLeave(int leaveDays) {
        if (this.getLeaveDays() >= leaveDays) {
            return this.handle();
        } else {
            if (Objects.nonNull(next)) {
                return next.handleLeave(leaveDays);
            } else {
                return "大老板都不能处理你的假期了~~";
            }
        }
    }
    /**
     * 具体处理
     *
     * @return 处理结果
     */
    protected abstract String handle();

    /**
     * 每个处理类能处理的天数,数据可以使数据库获取,这里简单就写死了
     *
     * @return 请假天数
     */
    protected abstract Integer getLeaveDays();

    /**
     * 设置下一个处理类
     *
     * @param next
     */
    public void setNext(AbstractHandler next) {
        this.next = next;
    }
}
复制代码

具体处理者

// 项目经理处理
public class PMHandler extends AbstractHandler {

    @Override
    protected String handle() {
        return "你的请假被项目经理处理了";
    }

    @Override
    protected Integer getLeaveDays() {
        return 1;
    }
}

// 项目总监处理
public class PDHandler extends AbstractHandler {
    @Override
    protected String handle() {
        return "你的请假被项目总监处理了";
    }

    @Override
    protected Integer getLeaveDays() {
        return 3;
    }
}

// 大老板处理
public class BossHandler extends AbstractHandler {
    @Override
    protected String handle() {
        return "你的请假被大老板处理了";
    }

    @Override
    protected Integer getLeaveDays() {
        return 7;
    }
}
复制代码

客户端

@Test
public void test() {
    PMHandler pmHandler = new PMHandler();
    PDHandler pdHandler = new PDHandler();
    BossHandler bossHandler = new BossHandler();

    pmHandler.setNext(pdHandler);
    pdHandler.setNext(bossHandler);

    String leaveRes = pmHandler.handleLeave(1);
    System.out.println(leaveRes);
    String leaveRes1 = pmHandler.handleLeave(3);
    System.out.println(leaveRes1);
    String leaveRes2 = pmHandler.handleLeave(7);
    System.out.println(leaveRes2);
    String leaveRes3 = pmHandler.handleLeave(8);
    System.out.println(leaveRes3);
}
复制代码

类图

责任链模式

优点

  1. 降低耦合度。它将请求的发送者和接收者解耦;
  2. 简化了对象。使得对象不需要知道链的结构;
  3. 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任;
  4. 增加新的请求处理类很方便。

缺点

  1. 请求没有明确的接收者,不能保证它一定会被处理,该请求可能一直到链的末端都得不到处理;
  2. 对于比较长的职责链,请求的处理可能涉及到多个处理对象,系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。

适用场景

  1. 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定;
  2. 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求;
  3. 可动态指定一组对象处理请求。

总结

责任链模式有两种使用形式:纯责任链模式和不纯的责任链模式。

如果一个类要么承担责任处理请求要么将请求踢给下一个皮球,则被称为纯责任链模式;如果一个类承担了一部分责任,还将请求踢给下一个皮球,则被称为不纯的责任链模式。纯的责任链模式的实际例子很难找到,一般看到的例子均是不纯的责任链模式的实现。

猜你喜欢

转载自juejin.im/post/5c99e2935188251d497ac14b