设计模式(17/23) - 责任链模式

94 阅读3分钟

责任链模式

1 概述

  • 责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它使得多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。这些对象通过将请求沿着链传递的方式,直到有一个对象处理它为止。
  • 责任链模式通过为多个对象创建一个链来处理请求,每个对象都有机会处理请求或将其传递给链中的下一个对象,从而实现了请求的灵活传递和处理。

2 优缺点及应用场景

2.1 优点

  • 1)降低耦合度:发送者和接收者解耦,发送者无需知道具体处理者。
  • 2)动态组合职责:可以在运行时动态添加或修改链中的处理者,灵活应对变化。
  • 3)增强系统的灵活性:通过责任链可以灵活组合多个处理对象,实现复杂的处理逻辑。

2.2 缺点

  • 1)降低性能:如果责任链过长,可能会导致性能问题。
  • 2)调试困难:由于请求的传递具有不确定性,可能会导致调试和跟踪问题变得复杂。

2.3 应用场景

  • 1)多个对象可以处理同一请求:系统中多个对象都有可能处理请求,但具体由哪个对象处理在运行时确定。
  • 2)动态指定处理者:需要在运行时动态指定请求的处理者。
  • 3)简化对象的职责:将处理请求的职责链分散到多个处理对象中,简化单个对象的职责。

3 结构

  • 1)处理者(Handler):定义处理请求的接口,并实现链的连接。
  • 2)具体处理者(ConcreteHandler):实现处理者接口,处理它负责的请求或将其传递给下一个处理者。
  • 3)客户端(Client):向链中的具体处理者对象提交请求。

4 实现

4.1 UML 类图

责任链模式.jpg

4.2 代码示例

// 创建抽象的记录器类
abstract class AbstractLogger {
  public static int INFO = 1;
  public static int DEBUG = 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);
    }
  }

  abstract protected void write(String message);
}

// 创建扩展了该记录器类的实体类:控制台日志记录器
class ConsoleLogger extends AbstractLogger {
  public ConsoleLogger(int level) {
    this.level = level;
  }

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

// 创建扩展了该记录器类的实体类:错误日志记录器
class ErrorLogger extends AbstractLogger {
  public ErrorLogger(int level) {
    this.level = level;
  }

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

// 创建扩展了该记录器类的实体类:文件日志记录器
class FileLogger extends AbstractLogger {
  public FileLogger(int level) {
    this.level = level;
  }

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

// 使用示例
public class ChainPatternDemo {
  private static AbstractLogger getChainOfLoggers() {
    AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);
    AbstractLogger fileLogger = new FileLogger(AbstractLogger.DEBUG);
    AbstractLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);

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

  public static void main(String[] args) {
    // 创建不同类型的记录器,赋予它们不同的错误级别,并在每个记录器中设置下一个记录器,每个记录器中的下一个记录器代表的是链的一部分
    AbstractLogger loggerChain = getChainOfLoggers();

    loggerChain.logMessage(AbstractLogger.INFO, "This is an information.");
    loggerChain.logMessage(AbstractLogger.DEBUG, "This is a debug level information.");
    loggerChain.logMessage(AbstractLogger.ERROR, "This is an error information.");
  }
}
  • 执行程序,输出结果:
Standard Console::Logger: This is an information.
File::Logger: This is a debug level information.
Standard Console::Logger: This is a debug level information.
Error Console::Logger: This is an error information.
File::Logger: This is an error information.
Standard Console::Logger: This is an error information.

5 总结

  • 责任链模式通过为多个对象创建一条处理请求的链,使得多个对象都有机会处理请求,从而实现请求的灵活传递和处理。责任链模式适用于多个对象可以处理同一请求、需要动态指定处理者以及简化对象职责的场景。尽管责任链模式降低了对象之间的耦合度,并增强了系统的灵活性,但也可能会导致性能问题和调试困难。在实际应用中,需要根据具体需求合理使用责任链模式,以实现灵活可扩展的系统设计。