Skip to content

责任链模式(Chain of Responsibility Pattern)

概念

责任链模式是一种行为设计模式,它允许多个对象有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

责任链模式的核心思想是将请求的发送者和接收者解耦,让多个对象都有机会处理这个请求。接收者和发送者都没有明确的引用,链中的对象自己负责判断是否能处理该请求。

基本实现

责任链模式包含以下主要角色:

  1. Handler(抽象处理者):定义一个处理请求的接口,通常包含一个指向下一个处理者的引用。
  2. ConcreteHandler(具体处理者):处理它所负责的请求,如果不能处理,则将请求转发给它的后继者。
  3. Client(客户端):向链上的具体处理者对象提交请求。

下面是责任链模式的基本实现:

javascript
// 抽象处理者
class Handler {
  constructor() {
    this.nextHandler = null;
  }

  // 设置下一个处理者
  setNext(handler) {
    this.nextHandler = handler;
    return handler;
  }

  // 处理请求的方法(子类需重写)
  handle(request) {
    if (this.nextHandler) {
      return this.nextHandler.handle(request);
    }
    return null;
  }
}

// 具体处理者A
class ConcreteHandlerA extends Handler {
  handle(request) {
    if (request.type === 'A') {
      return `ConcreteHandlerA handled request: ${JSON.stringify(request)}`;
    }
    return super.handle(request);
  }
}

// 具体处理者B
class ConcreteHandlerB extends Handler {
  handle(request) {
    if (request.type === 'B') {
      return `ConcreteHandlerB handled request: ${JSON.stringify(request)}`;
    }
    return super.handle(request);
  }
}

// 具体处理者C
class ConcreteHandlerC extends Handler {
  handle(request) {
    if (request.type === 'C') {
      return `ConcreteHandlerC handled request: ${JSON.stringify(request)}`;
    }
    return super.handle(request);
  }
}

// 使用示例
const handlerA = new ConcreteHandlerA();
const handlerB = new ConcreteHandlerB();
const handlerC = new ConcreteHandlerC();

// 构建责任链: A -> B -> C
handlerA.setNext(handlerB).setNext(handlerC);

// 测试请求
console.log(handlerA.handle({ type: 'A', data: 'Data for A' }));
console.log(handlerA.handle({ type: 'B', data: 'Data for B' }));
console.log(handlerA.handle({ type: 'C', data: 'Data for C' }));
console.log(handlerA.handle({ type: 'D', data: 'Data for D' })); // 无法处理

实际应用场景

场景1:审批流程系统

在企业管理系统中,不同级别的审批需要由不同层级的管理者处理,这正是责任链模式的经典应用场景。

javascript
// 审批请求类
class PurchaseRequest {
  constructor(amount, purpose, requester) {
    this.amount = amount;
    this.purpose = purpose;
    this.requester = requester;
  }
}

// 抽象审批者
class Approver {
  constructor(name) {
    this.name = name;
    this.nextApprover = null;
  }

  setNext(approver) {
    this.nextApprover = approver;
    return approver;
  }

  approve(request) {
    if (this.nextApprover) {
      return this.nextApprover.approve(request);
    }
    return `审批请求被拒绝: ${request.requester} 的采购请求(${request.purpose})金额为 ${request.amount} 元`;
  }
}

// 主管审批者
class Supervisor extends Approver {
  approve(request) {
    if (request.amount <= 1000) {
      return `${this.name}(主管)批准了 ${request.requester} 的采购请求(${request.purpose}),金额为 ${request.amount} 元`;
    }
    console.log(`${this.name}(主管)无法批准 ${request.requester} 的采购请求,转交给上级`);
    return super.approve(request);
  }
}

// 经理审批者
class Manager extends Approver {
  approve(request) {
    if (request.amount <= 5000) {
      return `${this.name}(经理)批准了 ${request.requester} 的采购请求(${request.purpose}),金额为 ${request.amount} 元`;
    }
    console.log(`${this.name}(经理)无法批准 ${request.requester} 的采购请求,转交给上级`);
    return super.approve(request);
  }
}

// 总监审批者
class Director extends Approver {
  approve(request) {
    if (request.amount <= 10000) {
      return `${this.name}(总监)批准了 ${request.requester} 的采购请求(${request.purpose}),金额为 ${request.amount} 元`;
    }
    console.log(`${this.name}(总监)无法批准 ${request.requester} 的采购请求,转交给上级`);
    return super.approve(request);
  }
}

// 总裁审批者
class President extends Approver {
  approve(request) {
    if (request.amount > 10000) {
      return `${this.name}(总裁)批准了 ${request.requester} 的采购请求(${request.purpose}),金额为 ${request.amount} 元`;
    }
    return super.approve(request);
  }
}

// 使用示例
const supervisor = new Supervisor('张主管');
const manager = new Manager('李经理');
const director = new Director('王总监');
const president = new President('陈总裁');

// 构建审批链: 主管 -> 经理 -> 总监 -> 总裁
supervisor.setNext(manager).setNext(director).setNext(president);

// 测试不同的审批请求
const request1 = new PurchaseRequest(800, '办公用品', '小王');
const request2 = new PurchaseRequest(3000, '设备采购', '小李');
const request3 = new PurchaseRequest(8000, '市场推广', '小张');
const request4 = new PurchaseRequest(15000, '战略合作', '小赵');
const request5 = new PurchaseRequest(20000, '海外投资', '小刘');

console.log(supervisor.approve(request1));
console.log(supervisor.approve(request2));
console.log(supervisor.approve(request3));
console.log(supervisor.approve(request4));
console.log(supervisor.approve(request5));

场景2:Web 请求处理中间件

在 Node.js 或其他 Web 框架中,中间件就是一种典型的责任链模式实现,每个中间件处理请求的一部分,然后传递给下一个中间件。

javascript
// 请求和响应类
class Request {
  constructor(url, method, headers = {}, body = null) {
    this.url = url;
    this.method = method;
    this.headers = headers;
    this.body = body;
  }
}

class Response {
  constructor() {
    this.statusCode = 200;
    this.headers = {};
    this.body = '';
  }

  send(data) {
    this.body = data;
  }

  status(code) {
    this.statusCode = code;
    return this;
  }

  json(data) {
    this.headers['Content-Type'] = 'application/json';
    this.body = JSON.stringify(data);
  }
}

// 中间件处理者基类
class Middleware {
  constructor() {
    this.next = null;
  }

  setNext(middleware) {
    this.next = middleware;
    return middleware;
  }

  async handle(req, res) {
    if (this.next) {
      return await this.next.handle(req, res);
    }
  }
}

// 日志中间件
class LoggingMiddleware extends Middleware {
  async handle(req, res) {
    console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
    return await super.handle(req, res);
  }
}

// 认证中间件
class AuthMiddleware extends Middleware {
  async handle(req, res) {
    const authHeader = req.headers.authorization;
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      res.status(401).send('Unauthorized');
      return;
    }
    
    const token = authHeader.substring(7);
    if (token !== 'valid-token') {
      res.status(401).send('Invalid token');
      return;
    }
    
    console.log('Authentication successful');
    return await super.handle(req, res);
  }
}

// 解析Body中间件
class BodyParserMiddleware extends Middleware {
  async handle(req, res) {
    if (req.method === 'POST' || req.method === 'PUT') {
      try {
        req.body = JSON.parse(req.body);
      } catch (error) {
        res.status(400).send('Invalid JSON');
        return;
      }
    }
    return await super.handle(req, res);
  }
}

// 路由处理中间件
class RouteMiddleware extends Middleware {
  constructor() {
    super();
    this.routes = new Map();
  }

  addRoute(method, path, handler) {
    const key = `${method}:${path}`;
    this.routes.set(key, handler);
  }

  async handle(req, res) {
    const key = `${req.method}:${req.url}`;
    const handler = this.routes.get(key);
    
    if (handler) {
      await handler(req, res);
    } else {
      res.status(404).send('Not Found');
    }
  }
}

// 应用程序类
class Application {
  constructor() {
    this.middlewares = [];
  }

  use(middleware) {
    this.middlewares.push(middleware);
    return this;
  }

  // 连接中间件形成责任链
  buildChain() {
    for (let i = 0; i < this.middlewares.length - 1; i++) {
      this.middlewares[i].setNext(this.middlewares[i + 1]);
    }
  }

  async handleRequest(req, res) {
    this.buildChain();
    if (this.middlewares.length > 0) {
      await this.middlewares[0].handle(req, res);
    }
  }
}

// 使用示例
const app = new Application();

// 创建中间件实例
const logging = new LoggingMiddleware();
const auth = new AuthMiddleware();
const bodyParser = new BodyParserMiddleware();
const router = new RouteMiddleware();

// 添加路由
router.addRoute('GET', '/users', (req, res) => {
  res.json([{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]);
});

router.addRoute('POST', '/users', (req, res) => {
  res.status(201).json({ id: 3, name: req.body.name, message: 'User created' });
});

// 注册中间件
app.use(logging)
   .use(auth)
   .use(bodyParser)
   .use(router);

// 模拟请求处理
async function simulateRequests() {
  // 成功的GET请求
  const req1 = new Request('/users', 'GET', { authorization: 'Bearer valid-token' });
  const res1 = new Response();
  await app.handleRequest(req1, res1);
  console.log('Response 1:', res1.statusCode, res1.body);

  // 成功的POST请求
  const req2 = new Request('/users', 'POST', 
    { authorization: 'Bearer valid-token' }, 
    JSON.stringify({ name: 'Charlie' })
  );
  const res2 = new Response();
  await app.handleRequest(req2, res2);
  console.log('Response 2:', res2.statusCode, res2.body);

  // 未授权请求
  const req3 = new Request('/users', 'GET', {});
  const res3 = new Response();
  await app.handleRequest(req3, res3);
  console.log('Response 3:', res3.statusCode, res3.body);
}

simulateRequests();

场景3:异常处理系统

在复杂的软件系统中,异常处理也可以采用责任链模式,根据异常类型和严重程度由不同的处理器处理。

javascript
// 异常类
class AppException {
  constructor(message, severity, type) {
    this.message = message;
    this.severity = severity; // low, medium, high, critical
    this.type = type;         // network, database, validation, system
  }
}

// 抽象异常处理器
class ExceptionHandler {
  constructor() {
    this.nextHandler = null;
  }

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

  handle(exception) {
    if (this.nextHandler) {
      return this.nextHandler.handle(exception);
    }
    return `未处理的异常: ${exception.message} (类型: ${exception.type}, 严重性: ${exception.severity})`;
  }
}

// 低级别异常处理器
class LowSeverityHandler extends ExceptionHandler {
  handle(exception) {
    if (exception.severity === 'low') {
      return `低级别异常处理器已处理: ${exception.message}`;
    }
    return super.handle(exception);
  }
}

// 数据库异常处理器
class DatabaseExceptionHandler extends ExceptionHandler {
  handle(exception) {
    if (exception.type === 'database') {
      if (exception.severity === 'medium') {
        return `数据库异常处理器已处理中等级别数据库异常: ${exception.message}`;
      } else if (exception.severity === 'high') {
        return `数据库异常处理器已处理高级别数据库异常: ${exception.message},已通知DBA团队`;
      }
    }
    return super.handle(exception);
  }
}

// 网络异常处理器
class NetworkExceptionHandler extends ExceptionHandler {
  handle(exception) {
    if (exception.type === 'network') {
      if (exception.severity === 'medium') {
        return `网络异常处理器已处理中等级别网络异常: ${exception.message},正在尝试重连`;
      } else if (exception.severity === 'high' || exception.severity === 'critical') {
        return `网络异常处理器已处理严重网络异常: ${exception.message},已启动备用网络通道并通知运维团队`;
      }
    }
    return super.handle(exception);
  }
}

// 系统级异常处理器
class SystemExceptionHandler extends ExceptionHandler {
  handle(exception) {
    if (exception.severity === 'critical') {
      return `系统级异常处理器已处理严重异常: ${exception.message},系统即将关闭以防止数据损坏`;
    }
    return super.handle(exception);
  }
}

// 验证异常处理器
class ValidationExceptionHandler extends ExceptionHandler {
  handle(exception) {
    if (exception.type === 'validation') {
      return `验证异常处理器已处理: ${exception.message},请检查输入数据`;
    }
    return super.handle(exception);
  }
}

// 异常处理系统
class ExceptionHandlingSystem {
  constructor() {
    // 创建处理器实例
    this.lowHandler = new LowSeverityHandler();
    this.validationHandler = new ValidationExceptionHandler();
    this.databaseHandler = new DatabaseExceptionHandler();
    this.networkHandler = new NetworkExceptionHandler();
    this.systemHandler = new SystemExceptionHandler();

    // 构建责任链
    this.lowHandler
      .setNext(this.validationHandler)
      .setNext(this.databaseHandler)
      .setNext(this.networkHandler)
      .setNext(this.systemHandler);
  }

  handleException(exception) {
    return this.lowHandler.handle(exception);
  }
}

// 使用示例
const exceptionSystem = new ExceptionHandlingSystem();

// 测试各种异常
const exceptions = [
  new AppException('用户名不能为空', 'low', 'validation'),
  new AppException('数据库连接超时', 'medium', 'database'),
  new AppException('主数据库宕机', 'high', 'database'),
  new AppException('网络连接中断', 'high', 'network'),
  new AppException('DNS服务器无响应', 'critical', 'network'),
  new AppException('磁盘空间不足', 'critical', 'system'),
  new AppException('未知错误', 'medium', 'unknown')
];

exceptions.forEach((exception, index) => {
  console.log(`\n--- 异常 ${index + 1} ---`);
  console.log(`输入: ${exception.message} (类型: ${exception.type}, 严重性: ${exception.severity})`);
  console.log(`处理结果: ${exceptionSystem.handleException(exception)}`);
});

关键要点

  1. 降低耦合度:请求发送者和接收者之间没有直接引用关系,发送者不需要知道是谁处理了请求。

  2. 增强灵活性:可以动态地增加或删除责任,改变处理逻辑。

  3. 简化对象:对象不需要知道链的结构,只需要保持一个指向其后继者的引用。

  4. 不符合单一职责原则:一个类可能承担了太多职责,既处理请求又维护后继者引用。

与其他模式的关系

  • 与组合模式结合:可以在组合模式的树形结构中使用责任链模式,沿着父节点向上处理请求。
  • 与装饰器模式类似:两者都依赖于递归组合来将行为分布到一系列对象之中。
  • 与状态模式区别:责任链中处理者可以随时改变,而在状态模式中状态转换是预定义的。

优缺点

优点:

  1. 降低耦合度:发送者和接收者都没有对方的明确引用,降低了对象间的耦合。
  2. 增强了给对象指派职责的灵活性:可以在运行时动态地增加或删除责任。
  3. 增加了新的请求处理类很方便:只需新增具体的处理者类并将其加入链中。

缺点:

  1. 不能保证请求一定被接收:可能没有任何对象处理请求。
  2. 系统性能受影响:较长的责任链会影响系统性能,且调试较为困难。
  3. 不利于观察运行时特征:不方便观察到底是谁处理了请求。

责任链模式在实际开发中非常有用,特别是在处理具有多个步骤或层级的业务流程时,能够有效地解耦各个处理环节,提高系统的可维护性和可扩展性。