系统化掌握Dart网络编程之Dio(二):责任链模式篇

前言

在软件系统的复杂交互中,请求的处理往往需要跨越多个层级或模块责任链模式 应运而生,它通过将处理对象串联为一条"逻辑流水线",让每个节点专注单一职责,实现请求的自动传递与动态分配。

这种模式如同精密传送带 :每个工位(处理者)自主判断能否处理任务,或将其递交给下一环节,既避免了发送者与接收者的强耦合,又赋予系统运行时灵活调整链路的能力。

从网络拦截器的双向过滤到多级审批流程的智能路由,责任链以优雅的链式结构,在权限控制日志处理异常兜底等场景中,为复杂逻辑提供了高扩展低侵入的解决方案,堪称分布式协作的典范设计。

千曲 而后晓声,观千剑 而后识器。虐它千百遍 方能通晓其真意

一、基本概念

1.1、本质定义

责任链模式 是一种 行为型设计模式,核心思想是:

多个对象都有机会处理请求,将这些处理对象连成一条链请求沿着链传递直到被处理为止

概念 含义
处理者链 由多个处理者对象组成的链式结构
请求传递 请求从链首开始传递,每个处理者决定处理或传递给下一个
解耦发送者与接收者 发送者不需要知道具体由哪个对象处理请求
动态扩展 可随时增删处理者,灵活调整处理流程

1.2、处理者链的本质

核心定义

多个 独立处理器对象 构成的链式结构,每个处理器持有下一个处理器的引用,形成 单向或双向处理通道

结构解析

dart 复制代码
// 链表式处理器实现
abstract class Handler {
  Handler? _next;  // 后继处理器引用
  
  void setNext(Handler next) => _next = next;
  
  void handle(Request request) {
    if (canHandle(request)) {
      process(request);
    } else {
      _next?.handle(request);  // 链式传递
    }
  }
  
  bool canHandle(Request request);  // 处理判断
  void process(Request request);   // 处理逻辑
}

动态构建示例

dart 复制代码
// 构建三级处理链
final handlerChain = FirstHandler()
  ..setNext(SecondHandler())
  ..setNext(FinalHandler());

// 请求处理流程
// Request → FirstHandler → SecondHandler → FinalHandler

关键特性

  • 拓扑结构 :支持线性链树形链环形链等多种结构。
  • 运行时可变动态增删处理器(如热更新过滤规则)。
  • 自包含性 :每个处理器只需关注自己的处理逻辑。

1.3、请求传递机制

传递逻辑流程图

graph TD A[请求进入] --> B{处理器A能否处理?} B -- 是 --> C[处理器A处理] B -- 否 --> D{传递给处理器B?} D -- 是 --> E[处理器B处理] D -- 否 --> F[结束传递]

关键处理策略

策略类型 实现方式 应用场景
短路传递 处理器处理后立即终止链条 权限校验失败拦截
全链路传递 所有处理器依次处理 日志记录链
条件分支传递 根据处理结果选择不同后继处理器 多条件审批流程

异步传递示例

dart 复制代码
// 异步处理器实现
mixin AsyncHandler on Handler {
  Future<void> handle(Request request) async {
    if (await canHandleAsync(request)) {
      await processAsync(request);
    } else {
      await _next?.handle(request);
    }
  }
  
  Future<bool> canHandleAsync(Request request);
  Future<void> processAsync(Request request);
}

1.4、解耦发送者与接收者

传统耦合模式

dart 复制代码
// 发送者直接依赖具体处理器
class Sender {
  final HandlerA _handlerA;
  final HandlerB _handlerB;

  void send(Request request) {
    if (_handlerA.canHandle(request)) {
      _handlerA.process(request);
    } else if (_handlerB.canHandle(request)) {
      _handlerB.process(request);
    }
  }
}

责任链解耦实现

dart 复制代码
// 发送者只需知道链入口
class DecoupledSender {
  final Handler _chainHead;

  void send(Request request) {
    _chainHead.handle(request);
  }
}

// 配置处理链
final chain = HandlerA()..setNext(HandlerB());
final sender = DecoupledSender(chain);

解耦优势

  • 降低复杂度 :发送者代码量减少90%
  • 提升扩展性 :新增处理器无需修改发送者。
  • 增强灵活性 :运行时动态替换处理链。

1.5、动态扩展能力

动态配置示例

dart 复制代码
// 可配置处理链管理器
class HandlerChain {
  final List<Handler> _handlers = [];
  
  void addHandler(Handler handler) => _handlers.add(handler);
  
  void handle(Request request) {
    for (var handler in _handlers) {
      if (handler.canHandle(request)) {
        handler.process(request);
        break; // 短路处理
      }
    }
  }
}

// 运行时动态配置
final chain = HandlerChain()
  ..addHandler(ValidationHandler())
  ..addHandler(CacheHandler(expiry: Duration(hours: 1)))
  ..addHandler(APIClient());

扩展场景

  • A/B测试:为不同用户组配置不同处理链。
  • 灰度发布:逐步添加新处理器到生产环境。
  • 故障切换:自动剔除故障处理器并替换。

1.6、概念关联图示

classDiagram class Client { +send(Request) } class Handler { <> +setNext(Handler) +handle(Request) +canHandle(Request)* +process(Request)* } class ConcreteHandlerA { +canHandle(Request) +process(Request) } class ConcreteHandlerB { +canHandle(Request) +process(Request) } Client --> Handler Handler <|-- ConcreteHandlerA Handler <|-- ConcreteHandlerB Handler --> Handler : _next

二、核心组件实现

2.1、抽象处理者(Handler

dart 复制代码
/// 链表式处理器实现
abstract class Handler {
  /// 链中的下一个处理者
  Handler? _nextHandler;

  /// 设置下一个处理者
  Handler setNext(Handler handler) {
    _nextHandler = handler;
    return handler; // 支持链式调用
  }

  /// 处理请求的模板方法
  void handleRequest(String request) {
    if (canHandle(request)) {
      doHandle(request);
    } else if (_nextHandler != null) {
      _nextHandler!.handleRequest(request);
    } else {
      defaultHandler(request);
    }
  }

  /// 判断是否能处理请求(由子类实现)
  bool canHandle(String request);

  /// 具体处理逻辑(由子类实现)
  void doHandle(String request);

  /// 默认处理方式
  void defaultHandler(String request) {
    print("⚠️ 没有处理者能处理请求:$request");
  }
}

2.2、具体处理者

dart 复制代码
/// 处理者A:处理长度<=5的请求
class LengthHandler extends Handler {
  @override
  bool canHandle(String request) => request.length <= 5;

  @override
  void doHandle(String request) {
    print("🟢 LengthHandler 处理请求:'$request' (长度=${request.length})");
  }
}

/// 处理者B:处理包含"VIP"的请求
class VIPHandler extends Handler {
  @override
  bool canHandle(String request) => request.contains("VIP");

  @override
  void doHandle(String request) {
    print("🔵 VIPHandler 处理特殊请求:'$request'");
  }
}

/// 处理者C:处理数字请求
class NumberHandler extends Handler {
  @override
  bool canHandle(String request) => RegExp(r'^\d+$').hasMatch(request);

  @override
  void doHandle(String request) {
    print("🟡 NumberHandler 处理数字请求:'$request'");
  }
}

2.3、客户端使用

dart 复制代码
void main() {
  /// 1. 创建处理链
  final handlerChain = LengthHandler()
    ..setNext(VIPHandler())
    ..setNext(NumberHandler());

  /// 2. 发送不同请求
  const requests = ['123', 'HelloVIP', '567890', 'TooLongRequest', 'VIP123'];

  for (final request in requests) {
    print("\n🚀 发送请求:'$request'");
    handlerChain.handleRequest(request);
  }
}

输出结果

arduino 复制代码
🚀 发送请求:'123'
🟢 LengthHandler 处理请求:'123' (长度=3)

🚀 发送请求:'HelloVIP'
⚠️ 没有处理者能处理请求:HelloVIP

🚀 发送请求:'567890'
🟡 NumberHandler 处理数字请求:'567890'

🚀 发送请求:'TooLongRequest'
⚠️ 没有处理者能处理请求:TooLongRequest

🚀 发送请求:'VIP123'
⚠️ 没有处理者能处理请求:VIP123

三、模式运作流程图

sequenceDiagram participant Client participant HandlerA participant HandlerB participant HandlerC Client->>HandlerA: 发送请求 HandlerA->>HandlerA: 能否处理? alt 能处理 HandlerA-->>Client: 处理完成 else 不能处理 HandlerA->>HandlerB: 传递请求 HandlerB->>HandlerB: 能否处理? alt 能处理 HandlerB-->>Client: 处理完成 else 不能处理 HandlerB->>HandlerC: 传递请求 HandlerC->>HandlerC: 能否处理? alt 能处理 HandlerC-->>Client: 处理完成 else 不能处理 HandlerC-->>Client: 无法处理 end end end

四、模式核心特点

  • 1、链式结构
    • 处理者通过 setNext 方法形成链条。
    • 请求沿链传递,直到被处理或到达链尾。
  • 2、处理判断逻辑
    • 每个处理者通过 _canHandle 决定是否处理。
    • 处理者之间完全解耦,只需关注自己的处理范围。
  • 3、扩展性
    • 新增处理者只需继承 Handler 并实现两个方法。
    • 无需修改已有代码,符合开闭原则

五、实际应用场景

5.1、典型使用场景

场景 案例实现
网络请求拦截 Dio拦截器、OkHttp拦截器
事件处理系统 GUI事件传播(如Flutter手势竞争)
工作流审批系统 多级审批流程(经理→总监→CEO)
日志处理管道 日志级别过滤 → 格式转换 → 输出目标选择
异常处理系统 本地缓存 → 网络重试 → 全局降级

5.2、审批系统

dart 复制代码
abstract class Approver {
  Approver? next;

  bool handle(ApprovalRequest request) {
    if (_canHandle(request)) {
      print("✅ [$runtimeType] 批准金额:$${request.amount.toStringAsFixed(2)}");
      return true;
    }

    if (next != null) {
      return next!.handle(request);
    }

    print("❌ 金额 $${request.amount} 超出所有审批人权限");
    return false;
  }

  bool _canHandle(ApprovalRequest request); // 抽象方法
}

// ---------- 具体审批人 ----------
class Manager extends Approver {
  @override
  bool _canHandle(ApprovalRequest request) => request.amount <= 10000;
}

class Director extends Approver {
  @override
  bool _canHandle(ApprovalRequest request) => request.amount <= 50000;
}

class CEO extends Approver {
  @override
  bool _canHandle(ApprovalRequest request) => true; // 无金额限制
}

class ApprovalRequest {
  final double amount;

  ApprovalRequest(this.amount);
}

void main() {
  // 构建审批链:经理 → 总监 → CEO
  final manager = Manager();
  final director = Director();
  final ceo = CEO();

  manager.next = director;
  director.next = ceo;

  // 测试用例
  final testAmounts = [8000.0, 25000.0, 100000.0];

  for (final amount in testAmounts) {
    print("\n=== 处理申请:$${amount.toStringAsFixed(2)} ===");
    manager.handle(ApprovalRequest(amount));
  }
}

输出结果:
=== 处理申请:$8000.00 ===
✅ [Manager] 批准金额:$8000.00

=== 处理申请:$25000.00 ===
✅ [Director] 批准金额:$25000.00

=== 处理申请:$100000.00 ===
✅ [CEO] 批准金额:$100000.00

5.3、网络请求过滤

dart 复制代码
import 'dart:io';
import 'dart:convert';

/// ------------------ 核心抽象定义 ------------------
abstract class Handler {
  Handler? _next;

  Handler setNext(Handler next) {
    _next = next;
    return this;
  }

  Future<Response> handle(Request request) async {
    if (await canHandle(request)) {
      return await process(request);
    } else if (_next != null) {
      return await _next!.handle(request);
    } else {
      return Response(404, 'Not Found');
    }
  }

  bool canHandle(Request request);
  Future<Response> process(Request request);
}

/// ------------------ 具体模型定义 ------------------
class Request {
  final String method;
  final Uri uri;
  final Map<String, String> headers;

  Request.get(this.uri, {this.headers = const {}}) : method = 'GET';
}

class Response {
  final int statusCode;
  final String body;

  Response(this.statusCode, this.body);
}

/// ------------------ 具体处理者实现 ------------------
class LogHandler extends Handler {
  @override
  bool canHandle(Request request) => true;

  @override
  Future<Response> process(Request request) async {
    final stopwatch = Stopwatch()..start();
    print('📥 请求开始: ${request.uri}');

    try {
      final response = await _next?.handle(request) ?? Response(404, 'Not Found');
      print('📤 请求完成 (${stopwatch.elapsedMilliseconds}ms)');
      return response;
    } catch (e) {
      print('💥 请求异常: $e');
      return Response(500, 'Server Error');
    }
  }
}

class AuthHandler extends Handler {
  final String _validToken;

  AuthHandler(this._validToken);

  @override
  bool canHandle(Request request) {
    return request.headers.containsKey('Authorization');
  }

  @override
  Future<Response> process(Request request) async {
    final token = request.headers['Authorization']!.split(' ').last;
    if (token != _validToken) {
      return Response(401, 'Unauthorized');
    }
    print('🔑 认证通过');
    return await _next?.handle(request) ?? Response(404, 'Not Found');
  }
}

class HttpClientHandler extends Handler {
  final HttpClient _client = HttpClient();

  @override
  bool canHandle(Request request) => true;

  @override
  Future<Response> process(Request request) async {
    try {
      final req = await _client.getUrl(request.uri);
      request.headers.forEach((key, value) => req.headers.add(key, value));

      final res = await req.close();
      final body = await res.transform(utf8.decoder).join();

      return Response(res.statusCode, body);
    } finally {
      _client.close();
    }
  }
}

// ------------------ 使用示例 ------------------
void main() async {
  // 构建处理链
  final logHandler = LogHandler();
  final authHandler = AuthHandler('valid_token_123');
  final httpClientHandler = HttpClientHandler();

  logHandler.setNext(authHandler);
  authHandler.setNext(httpClientHandler);

  // 测试用例
  final testCases = [
    Request.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1')),
    Request.get(
        Uri.parse('https://jsonplaceholder.typicode.com/posts/1'),
        headers: {'Authorization': 'Bearer valid_token_123'}
    ),
    Request.get(Uri.parse('https://invalid.url'))
  ];

  for (var request in testCases) {
    print('\n${'=' * 40}');
    print('测试请求: ${request.uri}');

    final response = await logHandler.handle(request);
    print('状态码: ${response.statusCode}');
    print('响应长度: ${response.body.length}字符');
  }
}

输出结果:
========================================
测试请求: https://jsonplaceholder.typicode.com/posts/1
📥 请求开始: https://jsonplaceholder.typicode.com/posts/1
📤 请求完成 (736ms)
状态码: 200
响应长度: 292字符

========================================
测试请求: https://jsonplaceholder.typicode.com/posts/1
📥 请求开始: https://jsonplaceholder.typicode.com/posts/1
🔑 认证通过
💥 请求异常: Bad state: Client is closed
状态码: 500
响应长度: 12字符

========================================
测试请求: https://invalid.url
📥 请求开始: https://invalid.url
💥 请求异常: Bad state: Client is closed
状态码: 500
响应长度: 12字符

六、模式优缺点对比

优点 缺点
✅ 降低耦合度:请求发送者无需知道处理细节 ❌ 请求可能未被处理(需兜底逻辑)
✅ 动态调整处理流程 ❌ 长链影响性能
✅ 符合单一职责原则 ❌ 调试难度增加
✅ 方便扩展新处理者 ❌ 可能产生循环调用

七、最佳实践建议

1、控制链长度

  • 建议不超过5个处理者
  • 复杂场景可分级处理

2、设置兜底处理

dart 复制代码
class DefaultHandler extends Handler {
  @override
  bool _canHandle(String request) => true; // 最后执行

  @override
  void _doHandle(String request) {
    print("⚠️ 默认处理:$request");
  }
}

3、性能优化

dart 复制代码
// 缓存处理能力判断
final _cache = <String, bool>{};

@override
bool _canHandle(String request) => 
    _cache.putIfAbsent(request, () => _calculateCanHandle(request));

八、总结

通过深入理解责任链模式,我们可以更好地设计可扩展的中间件系统。关键在于:

  • 1、合理划分处理边界
  • 2、明确传递/中断策略
  • 3、谨慎处理异步操作
  • 4、建立完善的监控机制

该模式在网络框架工作流引擎事件处理系统中广泛应用,是构建灵活系统架构的重要工具之一。

欢迎一键四连关注 + 点赞 + 收藏 + 评论

相关推荐
ModestCoder_30 分钟前
将一个新的机器人模型导入最新版isaacLab进行训练(以unitree H1_2为例)
android·java·机器人
robin_suli1 小时前
Spring事务的传播机制
android·java·spring
鸿蒙布道师2 小时前
鸿蒙NEXT开发对象工具类(TS)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
Harrison_zhu3 小时前
Ubuntu18.04 编译 Android7.1代码报错
android
江上清风山间明月3 小时前
一周掌握Flutter开发--9. 与原生交互(下)
flutter·交互·原生·methodchannel
GeniuswongAir3 小时前
Flutter极速接入IM聊天功能并支持鸿蒙
flutter·华为·harmonyos
sayen4 小时前
记录 flutter 文本内容展示过长优化
前端·flutter
勤劳打代码4 小时前
剑拔弩张——焦点竞争引的发输入失效
flutter·客户端·设计
CYRUS STUDIO5 小时前
Unidbg Trace 反 OLLVM 控制流平坦化(fla)
android·汇编·算法·网络安全·逆向·ollvm
扫地的小何尚5 小时前
NVIDIA工业设施数字孪生中的机器人模拟
android·java·c++·链表·语言模型·机器人·gpu