# Repository 缓存层抽象优化 ## 问题描述 ### 现有架构 ``` ┌─────────────────────────────────────────┐ │ HybridCacheStore │ │ (Memory + Persistent 二级缓存) │ ├─────────────────────────────────────────┤ │ CacheEntry │ │ (value + fetchedAt 时间戳) │ ├─────────────────────────────────────────┤ │ CachePolicy │ │ (softTtl / hardTtl / minRefreshInterval)│ ├─────────────────────────────────────────┤ │ CacheInvalidator │ │ (统一失效管理) │ └─────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────┐ │ CalendarRepository │ ← 重复实现 │ TodoRepository │ ← 重复实现 │ UsersRepository │ ← 重复实现 │ ... │ └─────────────────────────────────────────┘ ``` ### 重复内容 | 重复内容 | 例子 | |---------|------| | key 命名空间 | `calendar:day:$day`、`todo:list:pending` | | 缓存读取逻辑 | `store.read>(key)` | | 数据转换 | API 返回 → CacheEntry 包装 | | 刷新逻辑 | `_refreshDayAndRead()` | | 强制刷新 | `forceRefresh` 参数处理 | | 后台刷新防重 | `_refreshInFlight` map | ### 涉及文件 - `apps/lib/features/calendar/data/services/calendar_repository.dart` - `apps/lib/features/todo/data/todo_repository.dart` - `apps/lib/features/contacts/data/users/users_repository_impl.dart` - `apps/lib/features/settings/data/services/user_profile_cache_repository.dart` ## 建议方案 ### 1. 抽取 `CachedRepository` 基类 ```dart abstract class CachedRepository { HybridCacheStore get store; CacheInvalidator get invalidator; CachePolicy get policy; String get namespace; // 'calendar', 'todo', etc. Future getOrLoad( String key, { bool forceRefresh = false, required Future Function() loader, }); Future invalidate(String key); String buildKey(String suffix); } ``` ### 2. 各模块简化 ```dart // CalendarRepository class CalendarRepository extends CachedRepository, ScheduleItemModel> { @override String get namespace => 'calendar'; @override Future> getDayEvents(DateTime date, {bool forceRefresh}) { return getOrLoad( 'day:${_formatDate(date)}', forceRefresh: forceRefresh, loader: () => calendarService.getEventsForDay(date), ); } String _formatDate(DateTime date) => '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}'; } // TodoRepository class TodoRepository extends CachedRepository, TodoResponse> { @override String get namespace => 'todo'; Future> getPendingTodos({bool forceRefresh = false}) { return getOrLoad( 'list:pending', forceRefresh: forceRefresh, loader: () => api.getPendingTodos(), ); } } ``` ### 3. 可选:泛型缓存装饰器 ```dart class CachedApiCall { final HybridCacheStore store; final CachePolicy policy; final String key; final DateTime Function() now; Future execute(Future Function() loader); } ``` ## 收益 | 收益 | 说明 | |------|------| | 减少重复代码 | 各 Repository 移除 60%+ 相似逻辑 | | 统一缓存行为 | 刷新策略、key 格式、并发控制一致 | | 易维护 | 修复 bug 或优化逻辑只需改一处 | | 易测试 | 基类可独立测试,子类继承即可 | ## 前置依赖 - 现有 `HybridCacheStore`、`CacheEntry`、`CachePolicy`、`CacheInvalidator` 已就绪 - 无需引入新依赖 ## 状态 - [ ] 待评估优先级 - [ ] 待设计 CachedRepository 基类接口 - [ ] 先在一个 Repository 上试点 - [ ] 推广到其他 Repository