责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它使得多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。这些处理对象构成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。

责任链模式通常适用于以下情况:

  • 有多个对象可以处理一个请求,具体哪个对象处理该请求由运行时刻自动确定。

  • 想在不明确接收者的情况下,向多个对象中的一个提交请求。

  • 可处理一个请求的对象集合应被动态指定。

角色和职责

  1. 处理器(Handler):定义了处理请求的接口,通常在这个接口中定义了一个方法来传递请求(如handleRequest)。此外,它还可以定义一个链接的方法,用来设置或获取链中的下一个接收者。

  2. 具体处理器(ConcreteHandler):处理它所负责的请求,可以访问它的后继者(如果有),如果它可以处理请求,则处理之,否则将请求转发给它的后继者。

  3. 客户端(Client):向链上的具体处理器(ConcreteHandler)提交请求。

示例

假设我们有一个简单的日志系统,不同级别的日志需要由不同级别的日志处理器来处理。日志级别可以是 INFO、DEBUG 和 ERROR。我们可以使用责任链模式来设计这个系统。

首先,定义Handler接口和几个具体的处理器:

// 处理器接口
public abstract class Logger {
    public static int INFO = 1;
    public static int DEBUG = 2;
    public static int ERROR = 3;

    protected int level;

    // 责任链中的下一个元素
    protected Logger nextLogger;

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

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

    abstract protected void write(String message);
    
}

// 具体处理器
public class ConsoleLogger extends Logger {

    public ConsoleLogger(int level){
        this.level = level;
    }

    @Override
    protected void write(String message) {       
        System.out.println("Standard Console::Logger: " + message);
    }
}

public class ErrorLogger extends Logger {

    public ErrorLogger(int level){
        this.level = level;
    }

    @Override
    protected void write(String message) {       
        System.out.println("Error Console::Logger: " + message);
    }
}

public class FileLogger extends Logger {

    public FileLogger(int level){
        this.level = level;
    }

    @Override
    protected void write(String message) {       
        System.out.println("File::Logger: " + message);
    }
}

然后,客户端可以这样组织责任链并使用它:

public class ChainPatternDemo {
    
    private static Logger getChainOfLoggers(){

        Logger errorLogger = new ErrorLogger(Logger.ERROR);
        Logger fileLogger = new FileLogger(Logger.DEBUG);
        Logger consoleLogger = new ConsoleLogger(Logger.INFO);

        errorLogger.setNextLogger(fileLogger);
        fileLogger.setNextLogger(consoleLogger);

        return errorLogger;  
    }

    public static void main(String[] args) {
        Logger loggerChain = getChainOfLoggers();

        loggerChain.logMessage(Logger.INFO, "This is an information.");
        loggerChain.logMessage(Logger.DEBUG, "This is a debug level information.");
        loggerChain.logMessage(Logger.ERROR, "This is an error information.");
    }
}

在这个例子中,我们创建了三个日志处理器(ConsoleLoggerFileLoggerErrorLogger),并按照它们的处理能力顺序将它们链接起来。每个处理器只处理指定级别或更高级别的日志请求。如果它不能处理某个请求,就会将请求传递给链中的下一个处理器。

这样的设计使得处理器不需要知道链中的其他处理