设计模式之责任链模式


1.定义

责任链模式属于行为型模式,顾名思义,为请求创建一个接收者对象的链,所有的对象都有可能接收到请求,请求沿着对象链传递,直到请求被处理,在这个过程中实现请求对象和接收对象的解耦,避免两者耦合在一起。

类比游戏中的副本关卡,挑战任务,或者日常生活中的等级考试,都可以理解为一个责任链。
比如软件应用中的web请求过滤器、拦截器实现,一个请求经过层层的过滤,对请求进行各种各样的处理,最后到达请求处理器,完成此次请求的处理。

责任链模式结构上有点类似于数据结构中的链表,将责任链上的对象通过next指针链接起来,然后沿着链向下调用,同时为了增加扩展性,将责任链上节点对象进行抽象,抽象出一个公共的抽象类。

责任链一般情况下是单向的链式结构,但是也可以根据需要实现成树形、环形、甚至其他的结构。

责任链角色总体上分为两类角色:

  • 抽象处理者角色(Handler):定义一个处理请求的接口,包含一个抽象处理方法和一个后继对象next指针
  • 具体处理者角色(Concrete Handler):实现抽象者的方法,实现自身的逻辑,判断是否能够处理本次请求,如果可以处理则处理,否则将请求转发给后继对象

UML:
在这里插入图片描述
图片来源:知乎

2.示例

以等级考试为例,对责任链模式进行简单实现,
张坤要想要进入某艺术学校,但需要进行考核,必须通过初试、复试,终试三个环节才能够进入艺术学校,于是张坤准备了三个节目来应对三场考核。

首先定义一个类表示节目:

/**
 * @description: 节目
 * @version: 1.0
 */
public class Item {
	//节目名称
    private String name;
	//分数
    private int score;

    public Item(String name, int score) {
        this.name = name;
        this.score = score;
    }

    public String getName() {
        return name;
    }

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

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }
}

对考试进行抽象,其中应持有下一场考试的引用

/**
 * @description: 抽象
 * @version: 1.0
 */
public abstract class TalentShow {

    protected TalentShow nextShow;

    private Item item;

    public TalentShow(Item item) {
        this.item = item;
    }

    public TalentShow getNextShow() {
        return nextShow;
    }

    public void setNextShow(TalentShow nextShow) {
        this.nextShow = nextShow;
    }

    public Item getItem() {
        return item;
    }

    public void setItem(Item item) {
        this.item = item;
    }


    public abstract int upgrade();
}

分别对次考试进行实现,实现要求初试必须满足60分以上才能进入复试,复试成绩比如满足70分以上才能进入终试,终试分数需要达到80分以上,才算符合入学条件

/**
 * @description: 初试
 * @version: 1.0
 */
public class PrimaryShow extends TalentShow{

    public PrimaryShow(Item item) {
        super(item);
    }

    @Override
    public int upgrade() {
        if (this .getItem().getScore() >= 60){
            System.out.println("分数大于60分,初试通过,进入下一轮复试");
            if (this.nextShow != null){
                this.nextShow.upgrade();
            }
        }
        return this .getItem().getScore();
    }
    
}
/**
 * @description: 复试
 * @version: 1.0
 */
public class SecondaryShow extends TalentShow{


    public SecondaryShow(Item item) {
        super(item);
    }

    @Override
    public int upgrade() {
        if (this.getItem().getScore() >= 70){
            System.out.println("分数大于70分,复试通过,进入下一轮终试");
            if (this.nextShow != null){
                this.nextShow.upgrade();
            }
        }
        return this.getItem().getScore();
    }
}
/**
 * @description: 终试
 * @create by      twotiger2tigersofast
 * @datetime 2023/4/8 0:25
 * @version: 1.0
 */
public class FinalShow extends TalentShow{


    public FinalShow(Item item) {
        super(item);
    }

    @Override
    public int upgrade() {
        if (this.getItem().getScore() >= 80){
            System.out.println("分数大于80分,终试通过,Congratulations!");
            if (this.nextShow != null){
                this.nextShow.upgrade();
            }
        }
        return this.getItem().getScore();
    }
}

测试:

/**
 * @description: test
 * @version: 1.0
 */
public class Test {
    public static void main(String[] args) {

        //初始化节目
        Item sing = new Item("唱",60);
        Item jump = new Item("跳",70);
        Item rap = new Item("Rap",80);

        //初试、复试、终试
        TalentShow primaryShow = new PrimaryShow(sing);
        TalentShow secondaryShow = new SecondaryShow(jump);
        TalentShow finalShow = new FinalShow(rap);

        //关联
        primaryShow.setNextShow(secondaryShow);
        secondaryShow.setNextShow(finalShow);

        primaryShow.upgrade();

    }
}

input:

分数大于60分,初试通过,进入下一轮复试
分数大于70分,复试通过,进入下一轮终试
分数大于80分,终试通过,Congratulations!
3.总结

责任链的优点是将请求和处理分开,请求者可以不同知道是谁处理的,处理者也可以不必知道请求的全貌,责任链的实现是灵活的,可以根据实际需要加入更多的扩展设计,比如将责任链对象实现配置化,设置优先级,比如gateway中的拦截器配置,spring中过滤器的getOrder。责任链的缺点就是如果责任链太长,会影响请求对象的处理时长,并且会增加调试的复杂性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值