# 责任链模式
# 概念
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,其核心思想是将请求的发送者和接收者解耦,允许多个对象按顺序处理请求。请求沿处理链传递,直到被某个处理者处理或链结束。
# 作用
1.解耦:发送者无需知道具体由哪个处理者处理请求,降低系统耦合度。
2.动态组合:可灵活调整处理链的顺序或增减处理者,适应业务变化。
3.单一职责:每个处理者专注自己的处理逻辑,符合单一职责原则。
# 场景
1.多级日志处理:根据日志级别选择不同输出方式(如控制台、文件、邮件)。
2.权限校验:依次检查用户权限(如登录态、角色、资源权限)。
3.请求过滤:Web 框架中的中间件链(如身份验证、缓存、压缩)。
# 举例
以下是使用责任链模式实现多级日志处理的Java代码示例:
// 抽象日志处理器
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
# 反例
如果不使用责任链模式,通常会通过条件分支硬编码处理逻辑,导致代码耦合度高且难以扩展:
// 硬编码条件判断的日志处理
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.违反开闭原则:新增日志处理器需修改log
方法,破坏封装性。
2.代码臃肿:条件分支随处理者增多变得复杂,难以维护。
3.复用性差:处理流程固化,无法动态调整或复用。
# 原理
责任链模式通过以下机制实现解耦和动态组合:
1.链式传递:每个处理者持有下一个处理者的引用,形成链式结构。
2.自处理判断:处理者根据自身逻辑决定是否处理请求或继续传递。
3.动态配置:通过修改链的顺序或增减节点,灵活控制处理流程。
# 缺点
1.性能损耗:长链可能导致遍历开销,需权衡性能与灵活性。
2.请求遗漏:若链未正确配置,请求可能未被处理,需完善终止条件。
总结
责任链模式通过链式传递和动态组合,解决了条件分支的硬编码问题,尤其适用于多级处理场景。其核心价值在于将处理逻辑分散到独立类中,提升代码的可维护性和扩展性,但需注意避免过度设计导致的性能问题。

微信公众号

QQ交流群
原创网站开发,偏差难以避免。
如若发现错误,诚心感谢反馈。
愿你倾心相念,愿你学有所成。
愿你朝华相顾,愿你前程似锦。
如若发现错误,诚心感谢反馈。
愿你倾心相念,愿你学有所成。
愿你朝华相顾,愿你前程似锦。