Skip to content

责任链模式

什么是责任链模式?

责任链模式是一种行为设计模式,它允许将请求的发送者和接收者解耦。通过将请求沿着处理链传递,直到有对象处理它为止。这样可以避免请求的发送者与接收者之间的紧耦合关系。

通俗易懂地说,它就像一个接力赛,每个参与者(处理者)都有机会接过“接力棒”(请求)并决定是否处理它。

示例代码

假设我们有一个简单的请求处理场景,使用多层 if 判断可能会导致代码变得复杂(如果多层 if 判断嵌套更不易于阅读):

js
function handleRequest(request: string) {
  if (request === 'A') {
    console.log('处理请求 A');
  } else if (request === 'B') {
    console.log('处理请求 B');
  } else if (request === 'C') {
    console.log('处理请求 C');
  } else {
    console.log('无处理');
  }
}

使用责任链模式后,可以将处理逻辑分散到不同的处理者中,代码变得更加简洁:

ts
// 处理者接口
interface Handler {
  setNext(handler: Handler): Handler;
  handleRequest(request: string): void;
}

// 具体处理者
class ConcreteHandlerA implements Handler {
  private nextHandler: Handler | null = null;

  setNext(handler: Handler): Handler {
    this.nextHandler = handler;
    return handler;
  }

  handleRequest(request: string): void {
    if (request === 'A') {
      console.log('处理请求 A');
    } else if (this.nextHandler) {
      this.nextHandler.handleRequest(request);
    }
  }
}

class ConcreteHandlerB implements Handler {
  private nextHandler: Handler | null = null;

  setNext(handler: Handler): Handler {
    this.nextHandler = handler;
    return handler;
  }

  handleRequest(request: string): void {
    if (request === 'B') {
      console.log('处理请求 B');
    } else if (this.nextHandler) {
      this.nextHandler.handleRequest(request);
    }
  }
}

// 客户端
const handlerA = new ConcreteHandlerA();
const handlerB = new ConcreteHandlerB();

handlerA.setNext(handlerB);

handlerA.handleRequest('A'); // 输出: 处理请求 A
handlerA.handleRequest('B'); // 输出: 处理请求 B
handlerA.handleRequest('C'); // 无输出

责任链模式的实现要素

  • 处理者接口(Handler):定义设置下一个处理者和处理请求的方法。
  • 具体处理者(ConcreteHandler):实现处理逻辑,若无法处理则传递请求。
  • 客户端:构造处理链并触发请求处理。

适用场景

  • 多级审批流程(如请假审批、费用报销)。
  • 中间件处理(如 HTTP 请求拦截器、日志过滤器)。
  • 事件传递系统(如 GUI 事件冒泡机制)。
  • 替换多层条件判断(如不同规则校验场景)。

优缺点

优点

  • 解耦合:请求的发送者与处理者之间不再直接耦合,发送者只需知道链的起始处理者,降低了系统的复杂性。
  • 可扩展性:可以轻松添加新的处理者,而无需修改现有的代码结构。只需创建新的处理者类并将其添加到链中,增强了系统的灵活性。
  • 清晰性:将不同的处理逻辑分散到不同的处理者中,提高了代码的可读性和可维护性。每个处理者只关注自己的处理逻辑,减少了代码的复杂性。
  • 责任分担:每个处理者只负责处理特定的请求,符合单一职责原则,便于管理和维护。

缺点

  • 性能开销:由于请求可能需要经过多个处理者,可能导致性能下降,尤其是在处理链较长时。
  • 调试困难:由于请求的处理逻辑分散在多个处理者中,调试时可能会变得复杂,难以追踪请求的处理路径。
  • 不易理解:不熟悉责任链模式的话,理解整个处理流程可能需要时间,增加了学习成本。

责任链模式和策略模式的区别

  • 策略模式强调算法的选择和替换,适用于需要灵活切换算法的场景。(选择算法,像是选择不同的工具来完成同一项工作。)
  • 责任链模式强调请求的处理和传递,适用于需要多个处理者共同处理请求的场景。(请求处理,像是把问题传给不同的人,直到找到能解决它的人)

总结

责任链模式通过链式传递请求的方式,有效解耦了请求发起者和处理者,常用于需要动态调整处理流程的场景(如审批系统、中间件)。其核心在于将多个条件分支转化为独立处理对象,提升代码可维护性,但需注意链长度和异常处理设计。