Java设计模式之责任链模式

发布于:2025-03-21 ⋅ 阅读:(24) ⋅ 点赞:(0)

概念

责任链模式将请求的发送者和接收者解耦,允许多个对象都有机会处理请求。请求沿处理链传递,直到被处理或链结束。

作用

1.解耦:发送者无需知道具体由哪个处理者处理请求。

2.动态组合:可灵活调整处理链的顺序或增减处理者。

3.单一职责:每个处理者专注自己的处理逻辑。

场景

1.多级日志处理:根据日志级别选择不同输出方式。

2.权限校验:依次检查用户权限(如登录态、角色、资源权限)。

3.请求过滤:Web 框架中的中间件链(如身份验证、缓存、压缩)。

示例

// 抽象日志处理器
public abstract class AbstractLogger {
    public static int DEBUG = 1;
    public static int INFO = 2;
    public static int ERROR = 3;

    protected int level;
    protected AbstractLogger nextLogger;

    public void setNextLogger(AbstractLogger nextLogger) {
        this.nextLogger = nextLogger;
    }

    public void logMessage(int level, String message) {
        if (this.level <= level) {
            write(message);
        }
        if (nextLogger != null) {
            nextLogger.logMessage(level, message);
        }
    }

    protected abstract void write(String message);
}
// 控制台日志(处理 DEBUG 及以上)
class ConsoleLogger extends AbstractLogger {
    public ConsoleLogger(int level) {
        this.level = level;
    }

    @Override
    protected void write(String message) {
        System.out.println("Console: " + message);
    }
}
// 文件日志(处理 INFO 及以上)
class FileLogger extends AbstractLogger {
    public FileLogger(int level) {
        this.level = level;
    }

    @Override
    protected void write(String message) {
        System.out.println("File: " + message);
    }
}
// 邮件日志(处理 ERROR)
class EmailLogger extends AbstractLogger {
    public EmailLogger(int level) {
        this.level = level;
    }

    @Override
    protected void write(String message) {
        System.out.println("Email: " + message);
    }
}
// 构建责任链
public class ChainDemo {
    public static void main(String[] args) {
        // 构建处理链:Console -> File -> Email
        AbstractLogger console = new ConsoleLogger(AbstractLogger.DEBUG);
        AbstractLogger file = new FileLogger(AbstractLogger.INFO);
        AbstractLogger email = new EmailLogger(AbstractLogger.ERROR);

        console.setNextLogger(file);
        file.setNextLogger(email);

        // 触发请求
        console.logMessage(AbstractLogger.DEBUG, "Debug message"); // 仅 Console 处理
        console.logMessage(AbstractLogger.INFO, "Info message"); // Console 和 File 处理
        console.logMessage(AbstractLogger.ERROR, "Error message");// 三者均处理
    }
}
Console: Debug message

Console: Info message
File: Info message

Console: Error message
File: Error message
Email: Error message

优点和缺点

优点

1.解耦性:请求发送者无需关注处理细节。

2.扩展性:新增处理者只需修改链结构,无需改动现有代码。

3.灵活性:动态调整处理顺序或禁用某些处理者。

缺点

1.性能损耗:长链可能导致遍历开销。

2.请求遗漏:若链未正确配置,请求可能未被处理。

无责任链模式的实现方式

若不用责任链模式,通常需通过条件分支硬编码处理逻辑,导致耦合:

// 硬编码条件判断的日志处理
public class LoggerWithoutChain {
    public void log(int level, String message) {
        if (level >= AbstractLogger.DEBUG) {
            System.out.println("Console: " + message);
        }
        if (level >= AbstractLogger.INFO) {
            System.out.println("File: " + message);
        }
        if (level >= AbstractLogger.ERROR) {
            System.out.println("Email: " + message);
        }
    }
}

问题

1.违反开闭原则:新增日志处理器需修改方法。

2.代码臃肿:条件分支随处理者增多变得复杂。

3.复用性差:难以动态调整处理流程。

总结

责任链模式通过链式传递动态组合解决了条件分支的硬编码问题,尤其适用于需要多级处理的场景。其核心价值在于将处理逻辑分散到独立的类中,提升代码的可维护性和扩展性。


网站公告

今日签到

点亮在社区的每一天
去签到