设计模式之责任链模式

130 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情

简介

责任链模式的定义是:

为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。

责任链模式是一种比较常见的涉及模式,在我们Servlet的Filter中,在Spring Security的校验链等框架中均有使用责任链模式。而在我们平时业务开发中也有很多场景是类似责任链模式的,比如很多业务规则的校验可能会有很多个,每一个都可以认为是责任链中的一环。

案例

我们通过体检这个场景作为案例来实现设计模式。相信大家一般去体检都是先取一个单子,然后去一个个科室去检查,先抽血、再量身高体重、然后验视力、做X光等等。。。这就是一个责任链的模型,每一个检查项都是责任链中的一环。

我们先给定义每一项检查工作定义一个抽象类。这个检查的抽象类中除了有一个检查的方法之外,还有一个setNextHandler方法设置下一个检查项目是什么。

public abstract class CheckHandler {
    private CheckHandler nextHandler;
    public void setNextHandler(CheckHandler checkHandler) {
        this.nextHandler = nextHandler;
    }
    protected abstract void check(Employee employee);
}

接下来我们要去实现各个检查项目了。第一个项目一般是抽血

public class BloodCheck extends CheckHandler{
    @Override
    protected void check(Employee employee) {
        System.out.println("blood check");
        if (Objects.nonNull(nextHandler)) {
            nextHandler.check(employee);
        }
    }
}

然后去做其他的项目,其他项目我们就随便来一个了

检查身高体重:

public class HeightWeightCheck extends CheckHandler {
    @Override
    protected void check(Employee employee) {
        System.out.println("heightweight check");
        if (Objects.nonNull(nextHandler)) {
            nextHandler.check(employee);
        }
    }
}

然后X光检查:

public class XrayCheck extends CheckHandler {
    @Override
    protected void check(Employee employee) {
        System.out.println("xray check");
        if (Objects.nonNull(nextHandler)) {
            nextHandler.check(employee);
        }
    }
}

最后就是咱们的应用类:

public class App {
    public static void main(String[] args) {
        BloodCheck bloodCheck = new BloodCheck();
        HeightWeightCheck heightWeightCheck = new HeightWeightCheck();
        XrayCheck xrayCheck = new XrayCheck();
        bloodCheck.setNextHandler(heightWeightCheck);
        heightWeightCheck.setNextHandler(xrayCheck);
        bloodCheck.check(new Employee());
    }
}

在应用类中,如果有下个检查项目的,需要通过setNetHandler来设置下个项目是啥。(这和我们真实体检时是类似的,从每个项目科室的房间出来,医生会给你建议下一项去哪里检查)。

总结

当然这里举的例子还是停留在示例层面,真正框架里用责任链一般通过建造者模式来构造责任链中的处理类形成链条,而且获取所有的责任链处理类也不是这样硬编码设置进去的,而且通过抽象类的子类和排序还构造责任链,这样也对链条做拓展,符合开闭原则。但是使用责任链模式的时候,要避免在链条内部死循环。