You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Clean Architecture实现UseCase重试与重执行功能方案咨询

实现思路与方案

要实现重新执行最近运行的UseCase和重试特定异常的失败UseCase,核心是跟踪每次UseCase的执行信息(实例、参数、结果),再基于这些记录完成重跑逻辑。以下是具体实现步骤:

1. 定义执行记录模型

先创建一个类存储每次UseCase的执行详情,包含实例、参数、执行结果和时间戳:

class UseCaseExecutionRecord<Type, Params> {
  final UseCase<Type, Params> useCase;
  final Params params;
  final Either<Failure, Type> result;
  final DateTime timestamp;

  UseCaseExecutionRecord({
    required this.useCase,
    required this.params,
    required this.result,
    DateTime? timestamp,
  }) : timestamp = timestamp ?? DateTime.now();
}

2. 实现历史管理器

创建管理器类,负责维护执行记录、提供重跑和重试方法:

class UseCaseHistoryManager {
  final List<UseCaseExecutionRecord> _executionRecords = [];

  // 记录一次UseCase执行
  void recordExecution<Type, Params>(
    UseCase<Type, Params> useCase,
    Params params,
    Either<Failure, Type> result,
  ) {
    _executionRecords.add(
      UseCaseExecutionRecord(
        useCase: useCase,
        params: params,
        result: result,
      ),
    );
    // 可选:限制记录数量,避免内存占用过高
    if (_executionRecords.length > 100) {
      _executionRecords.removeAt(0);
    }
  }

  // 获取最近一次执行记录
  UseCaseExecutionRecord? getLatestExecution() {
    return _executionRecords.isEmpty ? null : _executionRecords.last;
  }

  // 重新执行最近一次的UseCase
  Future<Either<Failure, Type>> retryLatestExecution<Type, Params>() async {
    final latestRecord = getLatestExecution();
    if (latestRecord == null) {
      return Left(Failure(message: '无最近执行的UseCase记录'));
    }

    final useCase = latestRecord.useCase as UseCase<Type, Params>;
    final params = latestRecord.params as Params;
    final newResult = await useCase.call(params);
    
    // 记录重试结果
    recordExecution(useCase, params, newResult);
    return newResult;
  }

  // 重试最近一次匹配特定异常的失败UseCase
  Future<Either<Failure, Type>> retryLatestFailed<Type, Params>(
    Type Function() targetException,
  ) async {
    // 从最新记录往前遍历,找到第一个匹配条件的失败记录
    for (final record in _executionRecords.reversed) {
      final result = record.result;
      if (result.isLeft()) {
        final failure = result.left;
        // 假设Failure类包含exception字段,需根据你的实际结构调整
        if (failure.exception.runtimeType == targetException().runtimeType) {
          final useCase = record.useCase as UseCase<Type, Params>;
          final params = record.params as Params;
          final newResult = await useCase.call(params);
          
          recordExecution(useCase, params, newResult);
          return newResult;
        }
      }
    }
    return Left(Failure(message: '未找到匹配的失败UseCase记录'));
  }
}

3. 调用与重试示例

基础调用与记录

假设你有一个具体的FetchUserUseCase实现,调用时通过管理器记录结果:

final userUseCase = FetchUserUseCase();
final params = FetchUserParams(userId: 123);
final historyManager = UseCaseHistoryManager();

// 执行UseCase并记录
final executionResult = await userUseCase.call(params);
historyManager.recordExecution(userUseCase, params, executionResult);

重新执行最近一次UseCase

final retryResult = await historyManager.retryLatestExecution<FetchUserResponse, FetchUserParams>();

重试最近一次NoInternetException的失败UseCase

final noInternetRetryResult = await historyManager.retryLatestFailed<FetchUserResponse, FetchUserParams>(
  () => NoInternetException(),
);

4. 扩展优化建议

  • 单例/依赖注入:将UseCaseHistoryManager设为单例或通过DI框架提供,确保全应用共享执行历史。
  • 持久化存储:如果需要重启应用后仍能重试,可将执行记录序列化后存储到本地(如Hive、SharedPreferences)。
  • 类型安全优化:可以通过泛型封装进一步避免类型转换,或者为不同UseCase类型维护独立的记录列表。
  • 重试次数控制:在重试方法中添加参数,支持指定重试次数。

内容的提问来源于stack exchange,提问作者coke_85

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 12:32:51