系统化掌握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、建立完善的监控机制

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

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

相关推荐
雨白2 小时前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
kk爱闹4 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
每次的天空5 小时前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭6 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日7 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安7 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑7 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
还鮟11 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡12 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi0013 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体