责任链模式的一个应用

概念

责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链,使多个对象都有机会处理同一个请求。这种模式中请求的发送者和接收者,以及接收者间都是解耦的。

应用

  1. 过滤器
  2. 复杂的ifelse判断,选用于判断条件和内容都复杂,或者内容复杂的情况
  3. OA系统中的审批

例子

实例的背景
之前看到这个模式感觉很适合现在项目中运输路线的规划,所以写了一个小demo
背景:假设根据实际运输的距离来判断生成运输路线使用哪种方案,距离小于10千米,不用调拔,10千米<距离<20千米,一级调拔,20千米<距离<30千米,二级调拔(实际情况是是很复杂的)

实例的类图

实例的代码

1.创建一个请求对象:TranslineQueryParam

public class TranslineQueryParam {
    private Integer distance;

    public Integer getDistance() {
        return distance;
    }

    public void setDistance(Integer distance) {
        this.distance = distance;
    }
}

2.创建一个结果对象:TranslineResult

public class TranslineResult {
    private String info;

    public String getInfo() {
        return info;
    }
    public void setInfo(String info) {
        this.info = info;
    }
}

3.创建一个抽象类:TranslineQueryHandler

public abstract class TranslineQueryHandler {
    //这个变量主要是给各个Handler起个名字,方便调试
    private String name;
    //这个字段一定要有,指定下一处理者
    private TranslineQueryHandler nextTranslineQueryHandler;

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

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

    public TranslineQueryHandler getNextTranslineQueryHandler() {
        return nextTranslineQueryHandler;
    }

    //给当前对象指定下一处理人,并返回【下一处理人】
    public TranslineQueryHandler setNextTranslineQueryHandler(TranslineQueryHandler next) {
        this.nextTranslineQueryHandler = next;
        System.out.println("-----处理人------"+this+"-----的下一处理人-----"+next);
        return next;
    }
    public String toString() {              // 显示字符串
        return "[" + name + "]";
    }

    //抽象方法deal:用于处理请求,所有处理人都要根据自身条件重写此方法
    public abstract TranslineResult deal(TranslineQueryParam translineQueryParam);

    //核心方法doChain:如果当前TranslineQueryHandler可以解决,就解决,如果不行,就调此方法交给next去解决
    protected void doChain(TranslineQueryParam translineQueryParam){
        if(this.nextTranslineQueryHandler != null){
            this.nextTranslineQueryHandler.deal(translineQueryParam);
        }
    }

}

这个类中的参数nextTranslineQueryHandler用来存放下一个请求处理对象,方法deal()用于处理请求,方法doChain()用于将参数传递给下一个处理对象。

4.创建责任链中的三个对象
对象一:不需要调拔

public class NoNeedWarehousesCross extends TranslineQueryHandler{

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

    @Override
    public TranslineResult deal(TranslineQueryParam translineQueryParam) {
        TranslineResult translineResult =new TranslineResult();
        if(translineQueryParam.getDistance()<10){
            System.out.println("--------------不需要调拔就可以找到运输路线-----------------------");
            translineResult.setInfo("--------------不需要调拔就可以找到运输路线-----------------------");
        }else {
            System.out.println("--------------进入调拔逻辑-----------------------");
            translineResult.setInfo("--------------进入调拔逻辑-----------------------");
            this.doChain(translineQueryParam);
        }
        return translineResult;

    }
}

对象二:一级调拔

public class OneTimeWarehousesCross extends TranslineQueryHandler{
    public OneTimeWarehousesCross(String name) {
        super(name);
    }

    @Override
    public TranslineResult deal(TranslineQueryParam translineQueryParam) {
        TranslineResult translineResult = new TranslineResult();
        if(translineQueryParam.getDistance()<20){
            System.out.println("--------------一级调拔可以找到运输路线-----------------------");
            translineResult.setInfo("--------------一级调拔可以找到运输路线-----------------------");
        }else {
            System.out.println("--------------进入二级调拔-----------------------");
            translineResult.setInfo("--------------进入二级调拔-----------------------");
            this.doChain(translineQueryParam);
        }
        return translineResult;
    }
}

对象三:二级调拔

public class TwoTimeWarehousesCross extends TranslineQueryHandler{
    public TwoTimeWarehousesCross(String name) {
        super(name);
    }

    @Override
    public TranslineResult deal(TranslineQueryParam translineQueryParam) {
        TranslineResult  translineResult = new TranslineResult();
        if(translineQueryParam.getDistance()<30){
            System.out.println("--------------两级调拔可以找到运输路线-----------------------");
            translineResult.setInfo("--------------两级调拔可以找到运输路线-----------------------");
        }else {
            System.out.println("--------------找不到运输路线-----------------------");
            translineResult.setInfo("--------------找不到运输路线-----------------------");
            this.doChain(translineQueryParam);
        }
        return translineResult;
    }
}

三个对象都是在做同样的事,根据条件看是否能处理请求,如果能处理则处理,不能处理就把请求传递给下一个对象,在实际的应用场景中也可以先处理请求,处理不成功再把请求传递给下一个对象。

5.将责任链上的对象组装并从发送请求给责任链上的第一个处理对象

public class TranslinesCalculate {

    public static void main(String[] args) {
        NoNeedWarehousesCross noNeedWarehousesCross = new NoNeedWarehousesCross("no");
        OneTimeWarehousesCross oneTimeWarehousesCross = new OneTimeWarehousesCross("one");
        TwoTimeWarehousesCross twoTimeWarehousesCross = new TwoTimeWarehousesCross("two");

        //组装责任链
        noNeedWarehousesCross.setNextTranslineQueryHandler(oneTimeWarehousesCross).setNextTranslineQueryHandler(twoTimeWarehousesCross);

        //链头部开始执行
        TranslineQueryParam translineQueryParam = new TranslineQueryParam();
        translineQueryParam.setDistance(18);
        noNeedWarehousesCross.deal(translineQueryParam);
    }
}

6.结果

思考

这只是责任链模式中最简单的一种代码实现,实际实现中可以根据业务要求用更灵活的方式实现

猜你喜欢

转载自blog.csdn.net/qq_39172525/article/details/83828716