• 设计模式:责任链模式


    模式概述

    责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

    责任链模式降低了对象之间的耦合度。该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息;增强了系统的可扩展性,可以根据需要增加新的请求处理类,满足开闭原则。责任链简化了对象之间的连接,每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。

    在责任链模式中,客户只需要将请求发送到责任链上即可,无须关心请求的处理细节和请求的传递过程,请求会自动进行传递。所以责任链将请求的发送者和请求的处理者解耦了。注意:责任链模式也叫职责链模式。

    责任链模式的本质是解耦请求与处理,让请求在处理链中能进行传递与被处理;理解责任链模式应当理解其模式,而不是其具体实现。责任链模式的独到之处是将其节点处理者组合成了链式结构,并允许节点自身决定是否进行请求处理或转发,相当于让请求流动起来。

    模式结构

    职责链模式主要包含三个部分:

    抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
    具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
    客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。

    在这里插入图片描述

    实现代码

    假设需要根据形状Shape的大小来调用对应的方法来调用draw画出相应的形状。比如给定一个size,如果0 SmallShape、MiddleShape和LargeShape是抽象类Shape的实现类,继承了Shape的setNext()和getNext()方法,用于请求的处理或转发。

    抽象处理者角色

    public abstract class Shape {
        private Shape shape;
    
        public void setNextShape(Shape shape){
            this.shape = shape;
        }
        public Shape getNextShape(){
            return shape;
        }
        public abstract void draw(int size);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    具体处理者角色

    public class SmallShape extends Shape{
        @Override
        public void draw(int size) {
            if(0 < size && size <= 10){
                System.out.println("small shape with size " + String.valueOf(size));
            } 
            else{
                if(this.getNextShape() != null){
                    getNextShape().draw(size);
                }
                else{
                    System.out.println("not exist!");
                }
            }       
        }
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    public class MiddleShape extends Shape{
        @Override
        public void draw(int size) {
            if(size > 10 && size <= 20){
                System.out.println("middle shape with size " + String.valueOf(size));
            }        
            else{
                if(this.getNextShape() != null){
                    this.getNextShape().draw(size);
                }
                else{
                    System.out.println("not exist!");
                }
            }
        }
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    public class LargeShape extends Shape{
        @Override
        public void draw(int size) {
            if(size > 20 && size <= 30){
                System.out.println("large shape with size " + String.valueOf(size));
            }        
            else{
                if(this.getNextShape() != null){
                    this.getNextShape().draw(size);
                }
                else{
                    System.out.println("not exist!");
                }
            }
        }
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    客户类角色

    public class Demo {
        public static void main(String[] args) {
            Shape smallShape = new SmallShape();
            Shape middleShape = new MiddleShape();
            Shape largeShape = new LargeShape();
    
            smallShape.setNextShape(middleShape);
            middleShape.setNextShape(largeShape);
    
            smallShape.draw(15);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    输出结果:

    middle shape with size 15
    
    • 1
  • 相关阅读:
    openGL 3D geometry 之数学部分
    .NET使用CsvHelper快速读取和写入CSV文件
    trunc函数与truncate函数的一点区别
    python深入理解super
    狂神。SpringBoot学习(1)
    2019款保时捷卡宴车发动机故障灯异常点亮
    二分查找算法合集
    基于jsp+mysql+SSM学生兼职网站-计算机毕业设计
    浏览器原理思维导图
    在国内购买GPT服务前的一定要注意!!!
  • 原文地址:https://blog.csdn.net/weixin_49346755/article/details/126003630