设计模式-责任链模式

作者持续关注 WPS二次开发专题系列,持续为大家带来更多有价值的WPS开发技术细节,如果能够帮助到您,请帮忙来个一键三连,更多问题请联系我(QQ:250325397)

目录

定义

特点

使用场景

优缺点

[(1) 优点](#(1) 优点)

[(2) 缺点](#(2) 缺点)

模式结构

具体实现

实际应用


定义

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

特点

避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

使用场景

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

优缺点

(1) 优点
    • 降低耦合度。它将请求的发送者和接收者解耦。
    • 简化了对象。使得对象不需要知道链的结构。
    • 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
    • 增加新的请求处理类很方便。
(2) 缺点
    • 不能保证请求一定被接收。
    • 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
    • 可能不容易观察运行时的特征,有碍于除错。

模式结构

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

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

具体实现

抽象类

java 复制代码
/**
 * 日志接口
 */
public interface ILogger {
    int INFO = 1;
    int DEBUG = 2;
    int ERROR = 3;

    /**
     * 记录日志
     * @param level 日志级别
     * @param msg 日志内容
     */
    void doLogger(int level, String msg, LoggerChain chain);
}

/**
 * 控制台打印日志
 */
public class ConsoleLogger implements ILogger {
    @Override
    public void doLogger(int level, String msg, LoggerChain chain) {
        //处理当前日志打印
        System.out.println("Console Logger::[" + level + "] " + msg);
        //继续向下处理
        chain.doLogger(level, msg, chain);
    }
}

/**
 * file级别的日志
 */
public class FileLogger implements ILogger {
    @Override
    public void doLogger(int level, String msg, LoggerChain chain) {
        //处理当前日志打印,写入到文件中
        System.out.println("Filter Logger::[" + level + "] " + msg);
        //继续向下处理
        chain.doLogger(level, msg, chain);
    }
}

/**
 * 日志校验器
 */
public class ValidateLogger implements ILogger {
    @Override
    public void doLogger(int level, String msg, LoggerChain chain) {
        msg = msg.replace("sdcard", "xxx");
        chain.doLogger(level, msg, chain);
    }
}

责任链类

java 复制代码
/**
 * 日志处理器链
 */
public class LoggerChain implements ILogger {
    //日志处理器列表
    private List<ILogger> loggerList = new ArrayList<>();

    //当前处理的索引,从0开始
    private int index;

    /**
     * 添加日志处理器
     */
    public LoggerChain addLogger(ILogger logger) {
        loggerList.add(logger);
        return this;
    }

    @Override
    public void doLogger(int level, String msg, LoggerChain chain) {
        if (index == loggerList.size()) {
            //处理到最后,则返回
            return;
        }
        //继续使用下一个日志处理器处理
        ILogger logger = loggerList.get(index);
        index ++;
        logger.doLogger(level, msg, chain);
    }
}

具体使用

java 复制代码
public class App {
    public static void main(String[] args) {

        LoggerChain logger = new LoggerChain();
        logger.addLogger(new ConsoleLogger())
        //可添加日志敏感内容过滤器或者日志加密器
                .addLogger(new ValidateLogger())
                .addLogger(new FileLogger());
        logger.doLogger(ILogger.INFO, "This is a test log msg, file path:/sdcard/test/test.pdf", logger);
    }
}

实际应用

  1. Spring中的拦截器,Servlet中的过滤器
  2. Android中View的touch事件冒泡
相关推荐
考虑考虑3 小时前
Jpa使用union all
java·spring boot·后端
用户3721574261354 小时前
Java 实现 Excel 与 TXT 文本高效互转
java
浮游本尊5 小时前
Java学习第22天 - 云原生与容器化
java
渣哥6 小时前
原来 Java 里线程安全集合有这么多种
java
间彧7 小时前
Spring Boot集成Spring Security完整指南
java
间彧7 小时前
Spring Secutiy基本原理及工作流程
java
数据智能老司机8 小时前
精通 Python 设计模式——创建型设计模式
python·设计模式·架构
Java水解8 小时前
JAVA经典面试题附答案(持续更新版)
java·后端·面试
数据智能老司机9 小时前
精通 Python 设计模式——SOLID 原则
python·设计模式·架构
洛小豆10 小时前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试