5.8 KiB
5.8 KiB
TransactionRecordRepository 重构总结
重构目标
简化账单仓储,移除内存聚合逻辑,将聚合逻辑移到Service层,提高代码可测试性和可维护性。
主要变更
1. 创建新的仓储层 (TransactionRecordRepository.cs)
简化后的接口方法:
QueryAsync- 统一的查询方法,支持多种筛选条件和分页CountAsync- 统一的计数方法GetDistinctClassifyAsync- 获取所有分类GetByEmailIdAsync- 按邮件ID查询GetUnclassifiedAsync- 获取未分类账单GetClassifiedByKeywordsAsync- 关键词查询已分类账单GetUnconfirmedRecordsAsync- 获取待确认账单BatchUpdateByReasonAsync- 批量更新分类UpdateCategoryNameAsync- 更新分类名称ConfirmAllUnconfirmedAsync- 确认待确认分类ExistsByEmailMessageIdAsync- 检查邮件是否存在ExistsByImportNoAsync- 检查导入编号是否存在
移除的方法(移到Service层):
GetDailyStatisticsAsync- 日统计GetDailyStatisticsByRangeAsync- 范围日统计GetMonthlyStatisticsAsync- 月度统计GetCategoryStatisticsAsync- 分类统计GetTrendStatisticsAsync- 趋势统计GetReasonGroupsAsync- 按摘要分组统计GetClassifiedByKeywordsWithScoreAsync- 关键词匹配(带分数)GetFilteredTrendStatisticsAsync- 过滤趋势统计GetAmountGroupByClassifyAsync- 按分类分组统计
2. 创建统计服务层 (TransactionStatisticsService.cs)
新增 ITransactionStatisticsService 接口和实现,负责所有聚合统计逻辑:
主要方法:
GetDailyStatisticsAsync- 日统计(内存聚合)GetDailyStatisticsByRangeAsync- 范围日统计(内存聚合)GetMonthlyStatisticsAsync- 月度统计(内存聚合)GetCategoryStatisticsAsync- 分类统计(内存聚合)GetTrendStatisticsAsync- 趋势统计(内存聚合)GetReasonGroupsAsync- 按摘要分组统计(内存聚合,解决N+1问题)GetClassifiedByKeywordsWithScoreAsync- 关键词匹配(内存计算相关度)GetFilteredTrendStatisticsAsync- 过滤趋势统计(内存聚合)GetAmountGroupByClassifyAsync- 按分类分组统计(内存聚合)
3. 创建DTO文件 (TransactionStatisticsDto.cs)
将统计相关的DTO类从Repository移到独立文件:
ReasonGroupDto- 按摘要分组统计DTOMonthlyStatistics- 月度统计数据CategoryStatistics- 分类统计数据TrendStatistics- 趋势统计数据
4. 更新Controller (TransactionRecordController.cs)
- 注入
ITransactionStatisticsService - 将所有统计方法的调用从
transactionRepository改为transactionStatisticsService - 将
GetPagedListAsync改为QueryAsync - 将
GetTotalCountAsync改为CountAsync - 将
GetByDateRangeAsync改为QueryAsync - 将
GetUnclassifiedCountAsync改为CountAsync
5. 更新Service层
SmartHandleService:
- 注入
ITransactionStatisticsService - 将
GetClassifiedByKeywordsWithScoreAsync调用改为使用统计服务
BudgetService:
- 注入
ITransactionStatisticsService - 将
GetCategoryStatisticsAsync调用改为使用统计服务
BudgetStatsService:
- 注入
ITransactionStatisticsService - 将所有
GetFilteredTrendStatisticsAsync调用改为使用统计服务
BudgetSavingsService:
- 注入
ITransactionStatisticsService - 将所有
GetAmountGroupByClassifyAsync调用改为使用统计服务
6. 更新测试文件
BudgetStatsTest.cs:
- 添加
ITransactionStatisticsServiceMock - 更新构造函数参数
- 将所有
GetFilteredTrendStatisticsAsyncMock调用改为使用统计服务
BudgetSavingsTest.cs:
- 添加
ITransactionStatisticsServiceMock - 更新构造函数参数
- 将所有
GetAmountGroupByClassifyAsyncMock调用改为使用统计服务
重构优势
1. 职责分离
- Repository层:只负责数据查询,返回原始数据
- Service层:负责业务逻辑和数据聚合
2. 可测试性提升
- Repository层的方法更简单,易于Mock
- Service层可以独立测试聚合逻辑
- 测试时可以精确控制聚合行为
3. 性能优化
- 解决了
GetReasonGroupsAsync中的N+1查询问题 - 将内存聚合逻辑集中管理,便于后续优化
- 减少了数据库聚合操作,避免大数据量时的性能问题
4. 代码可维护性
- 统一的查询接口
QueryAsync和CountAsync - 减少了代码重复
- 更清晰的职责划分
5. 扩展性
- 新增统计功能只需在Service层添加
- Repository层保持稳定,不受业务逻辑变化影响
测试结果
所有测试通过:
- BudgetStatsTest: 7个测试全部通过
- BudgetSavingsTest: 7个测试全部通过
- 总计: 14个测试全部通过
注意事项
1. 性能考虑
- 当前使用内存聚合,适合中小数据量
- 如果数据量很大,可以考虑在Service层使用分页查询+增量聚合
- 对于需要实时聚合的场景,可以考虑缓存
2. 警告处理
编译时有3个未使用参数的警告:
TransactionStatisticsService的textSegmentService参数未使用BudgetStatsService的transactionRecordRepository参数未使用BudgetSavingsService的transactionsRepository参数未使用
这些参数暂时保留,可能在未来使用,可以通过添加 _ = parameter; 来消除警告。
3. 向后兼容
- Controller的API接口保持不变
- 前端无需修改
- 数据库结构无变化
后续优化建议
- 添加缓存:对于频繁查询的统计数据,可以添加缓存机制
- 分页聚合:对于大数据量的聚合,可以实现分页聚合策略
- 异步优化:某些聚合操作可以并行执行以提高性能
- 监控指标:添加聚合查询的性能监控
- 单元测试:为
TransactionStatisticsService添加专门的单元测试