责任链模式(Chain of Responsibility Pattern)
概念
责任链模式是一种行为设计模式,它允许多个对象有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
责任链模式的核心思想是将请求的发送者和接收者解耦,让多个对象都有机会处理这个请求。接收者和发送者都没有明确的引用,链中的对象自己负责判断是否能处理该请求。
基本实现
责任链模式包含以下主要角色:
- Handler(抽象处理者):定义一个处理请求的接口,通常包含一个指向下一个处理者的引用。
- ConcreteHandler(具体处理者):处理它所负责的请求,如果不能处理,则将请求转发给它的后继者。
- 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)}`);
});关键要点
降低耦合度:请求发送者和接收者之间没有直接引用关系,发送者不需要知道是谁处理了请求。
增强灵活性:可以动态地增加或删除责任,改变处理逻辑。
简化对象:对象不需要知道链的结构,只需要保持一个指向其后继者的引用。
不符合单一职责原则:一个类可能承担了太多职责,既处理请求又维护后继者引用。
与其他模式的关系
- 与组合模式结合:可以在组合模式的树形结构中使用责任链模式,沿着父节点向上处理请求。
- 与装饰器模式类似:两者都依赖于递归组合来将行为分布到一系列对象之中。
- 与状态模式区别:责任链中处理者可以随时改变,而在状态模式中状态转换是预定义的。
优缺点
优点:
- 降低耦合度:发送者和接收者都没有对方的明确引用,降低了对象间的耦合。
- 增强了给对象指派职责的灵活性:可以在运行时动态地增加或删除责任。
- 增加了新的请求处理类很方便:只需新增具体的处理者类并将其加入链中。
缺点:
- 不能保证请求一定被接收:可能没有任何对象处理请求。
- 系统性能受影响:较长的责任链会影响系统性能,且调试较为困难。
- 不利于观察运行时特征:不方便观察到底是谁处理了请求。
责任链模式在实际开发中非常有用,特别是在处理具有多个步骤或层级的业务流程时,能够有效地解耦各个处理环节,提高系统的可维护性和可扩展性。