基于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
相关产品推荐
相关产品推荐

