相信读了上一篇文章你对责任链模式有了初步的了解,没读也没关系,上一篇文章是关于责任链模式的一个使用例子,阅读顺序无所谓,可以先看完这篇文章再回头去把我上一篇文章看看,相信两篇文章看下来你能对责任链模式有更加深入的理解。接下来我就详细的说说看责任链模式的优缺点以及在Java实际开发中的应用
请求发送者不需要知道具体的处理者是谁,也不需要关心请求是如何被处理的,只需将请求发送到链中即可。这减少了发送者和处理者之间的耦合度。
看到这里你或许有疑问什么是解耦,什么又是耦合度呢?下面就让我来简单的说明一下
这两个概念是软件设计中的两个重要概念,主要用于描述模块或组件之间的依赖关系和相互作用的紧密程度。
解耦是指减少模块或组件之间的依赖,使得它们可以独立地变化和演化。当两个模块或组件解耦时,修改一个模块不会对另一个模块产生影响,这提高了系统的灵活性和可维护性。
耦合度指的是模块或组件之间相互依赖的紧密程度。高耦合意味着模块之间有着紧密的依赖关系,修改一个模块可能需要同时修改其他模块。低耦合意味着模块之间依赖较少,可以相对独立地变化和演化。
在责任链模式中,请求发送者不需要知道具体的处理者是谁,也不需要关心请求是如何被处理的,只需将请求发送到链中即可。这种设计减少了发送者和处理者之间的耦合度,具体表现在以下几个方面:
发送者只需将请求发送到责任链,不需要直接调用具体的处理者。这使得发送者不依赖于具体的处理者实现,处理者的变化不会影响发送者。
每个处理者只处理自己职责范围内的请求,并决定是否将请求传递给下一个处理者。处理者之间的依赖性较低,可以独立变化。
可以根据需要动态地增加或修改处理者而不影响其他处理者。新增处理者时,只需修改链条的配置即可。
每个处理者只专注于处理自己职责范围内的请求,这有助于清晰地分离不同的处理逻辑。
责任链模式将复杂的处理过程分散到多个处理者中,避免了臃肿的处理逻辑,提高了代码的可维护性和可读性。
由于请求可能要经过链中的多个处理者处理,若链条过长,可能会影响性能。每个处理者的处理时间都会累积,从而导致请求处理时间变长。
请求在链中传递时,可能很难跟踪和调试,特别是在链条较长且处理逻辑复杂的情况下。
处理者的顺序在链条中是固定的,如果需要更改处理顺序,可能需要重新配置或修改链条的结构。
在Java开发中,责任链模式被广泛应用于各种场景,如日志处理、事件处理、请求过滤等。下面是来自一个非常常规的例子:
假设我们需要一个日志处理系统,不同的日志级别需要不同的处理方式,比如DEBUG级别的日志只打印到控制台,ERROR级别的日志需要发送邮件通知。
// 抽象处理者
abstract class Logger {
public static int DEBUG = 1;
public static int INFO = 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);
}
// 具体处理者1:控制台日志记录器
class ConsoleLogger extends Logger {
public ConsoleLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Console::Logger: " + message);
}
}
// 具体处理者2:文件日志记录器
class FileLogger extends Logger {
public FileLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("File::Logger: " + message);
}
}
// 具体处理者3:邮件日志记录器
class EmailLogger extends Logger {
public EmailLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Email::Logger: " + message);
}
}
// 测试责任链模式
public class ChainPatternDemo {
private static Logger getChainOfLoggers() {
Logger consoleLogger = new ConsoleLogger(Logger.DEBUG);
Logger fileLogger = new FileLogger(Logger.INFO);
Logger emailLogger = new EmailLogger(Logger.ERROR);
consoleLogger.setNextLogger(fileLogger);
fileLogger.setNextLogger(emailLogger);
return consoleLogger;
}
public static void main(String[] args) {
Logger loggerChain = getChainOfLoggers();
loggerChain.logMessage(Logger.DEBUG, "This is a DEBUG level information.");
loggerChain.logMessage(Logger.INFO, "This is an INFO level information.");
loggerChain.logMessage(Logger.ERROR, "This is an ERROR level information.");
}
}
首先我们定义了一个抽象的Logger类,包含了日志处理的基础逻辑和设置下一个处理者的方法。ConsoleLogger、FileLogger和EmailLogger是具体的处理者类,分别实现了具体的日志处理逻辑。在ChainPatternDemo类中,我们创建了一个包含ConsoleLogger、FileLogger和EmailLogger的责任链,并测试了不同级别的日志处理。通过这种方式,我们可以很容易地扩展日志处理系统,例如添加新的日志处理器,而不影响现有的处理者。
相信读完两篇关于责任链模式的文章你对责任链的了解已经很深了,那么就快去你的代码中试试吧,实践出真知!