124 lines
4.4 KiB
Markdown
124 lines
4.4 KiB
Markdown
|
|
# 服务层与 Repository 层职责混乱
|
|||
|
|
|
|||
|
|
## 问题描述
|
|||
|
|
|
|||
|
|
当前 `CalendarService`、`SettingsUserCache`、`UserProfileCacheRepository` 等服务/仓库职责边界模糊,存在大量重复逻辑和不必要的封装。
|
|||
|
|
|
|||
|
|
## 问题1:SettingsUserCache 不该存在
|
|||
|
|
|
|||
|
|
### 当前结构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
SettingsUserCache UserProfileCacheRepository
|
|||
|
|
┌─────────────────┐ ┌─────────────────────────┐
|
|||
|
|
│ - _cachedUser │ ←→ │ - HybridCacheStore │
|
|||
|
|
│ - getProfile() │ │ - CachePolicy │
|
|||
|
|
│ - set() │ │ - getProfile() │
|
|||
|
|
│ - invalidate() │ │ - setCached() │
|
|||
|
|
└─────────────────┘ └─────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 问题
|
|||
|
|
|
|||
|
|
- `SettingsUserCache` 只是给 `UserProfileCacheRepository` 包了一层内存缓存
|
|||
|
|
- 两者的 `getProfile()`、`invalidate()` 逻辑几乎相同
|
|||
|
|
- 这是重复包装,应该合并
|
|||
|
|
|
|||
|
|
## 问题2:Repository 缓存逻辑重复
|
|||
|
|
|
|||
|
|
### 涉及文件
|
|||
|
|
|
|||
|
|
- `apps/lib/features/calendar/data/services/calendar_repository.dart`
|
|||
|
|
- `apps/lib/features/settings/data/services/user_profile_cache_repository.dart`
|
|||
|
|
- `apps/lib/features/todo/data/todo_repository.dart`
|
|||
|
|
|
|||
|
|
### 代码重复率:90%
|
|||
|
|
|
|||
|
|
```dart
|
|||
|
|
// CalendarRepository
|
|||
|
|
Future<List<ScheduleItemModel>> getDayEvents({bool forceRefresh}) async {
|
|||
|
|
if (forceRefresh) return _refreshDayAndRead(...);
|
|||
|
|
final cached = await store.read<CacheEntry<...>>(key);
|
|||
|
|
if (cached == null) return _refreshDayAndRead(...);
|
|||
|
|
final decision = policy.evaluate(now: now(), fetchedAt: cached.fetchedAt);
|
|||
|
|
if (decision.shouldRefreshInBackground) _refreshInBackground();
|
|||
|
|
if (decision.mustBlockForNetwork || !decision.canUseCached) {
|
|||
|
|
return _refreshDayAndRead(...);
|
|||
|
|
}
|
|||
|
|
return cached.value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// UserProfileCacheRepository
|
|||
|
|
Future<UserResponse> getProfile({bool forceRefresh}) async {
|
|||
|
|
if (forceRefresh) return _refreshAndRead();
|
|||
|
|
final cached = await store.read<CacheEntry<...>>(cacheKey);
|
|||
|
|
if (cached == null) return _refreshAndRead();
|
|||
|
|
final decision = policy.evaluate(now: now(), fetchedAt: cached.fetchedAt);
|
|||
|
|
if (decision.shouldRefreshInBackground) _refreshInBackground();
|
|||
|
|
if (decision.mustBlockForNetwork || !decision.canUseCached) {
|
|||
|
|
return _refreshAndRead();
|
|||
|
|
}
|
|||
|
|
return cached.value;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 问题3:CalendarService 不必要的延迟初始化
|
|||
|
|
|
|||
|
|
```dart
|
|||
|
|
class CalendarService {
|
|||
|
|
CalendarApi? _calendarApi;
|
|||
|
|
|
|||
|
|
CalendarApi get _api {
|
|||
|
|
if (_calendarApi != null) return _calendarApi;
|
|||
|
|
_calendarApi = CalendarApi(_apiClient); // 为什么懒加载?
|
|||
|
|
return _calendarApi;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
已经传入了 `IApiClient`,API 还在构造时懒加载,多此一举。
|
|||
|
|
|
|||
|
|
## 问题4:分层不清
|
|||
|
|
|
|||
|
|
| 类名 | 类型 | 问题 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| `CalendarService` | Service | 依赖 Repository,该叫 Repository |
|
|||
|
|
| `UserProfileCacheRepository` | Repository | 名字带 Cache,但 Repository 都带缓存 |
|
|||
|
|
| `SettingsUserCache` | ??? | 内存缓存层,不该独立存在 |
|
|||
|
|
| `TodoRepository` | Repository | 正确 |
|
|||
|
|
|
|||
|
|
## 应该的设计
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Repository 层(纯数据 + 缓存)
|
|||
|
|
├── CalendarRepository ← 继承 CachedRepository
|
|||
|
|
├── UserProfileRepository ← 继承 CachedRepository
|
|||
|
|
└── TodoRepository ← 继承 CachedRepository
|
|||
|
|
|
|||
|
|
Service 层(业务逻辑 + 跨 Repository 编排)
|
|||
|
|
├── CalendarService ← 只做业务编排,不直接调 API
|
|||
|
|
├── NotificationService ← 跨模块通知逻辑
|
|||
|
|
└── ReminderActionExecutor ← 跨模块提醒执行
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 修复步骤
|
|||
|
|
|
|||
|
|
1. **删除** `SettingsUserCache`,合并到 `UserProfileCacheRepository`
|
|||
|
|
2. **抽取** `CachedRepository` 基类(见 `docs/todo/2026-03-27-repository缓存抽象.md`)
|
|||
|
|
3. **简化** `CalendarService`,移除不必要的懒加载
|
|||
|
|
4. **统一命名**:
|
|||
|
|
- 带缓存的 Repository 统一继承基类
|
|||
|
|
- Service 只做业务编排,不处理缓存
|
|||
|
|
|
|||
|
|
## 涉及文件
|
|||
|
|
|
|||
|
|
- `apps/lib/features/calendar/data/services/calendar_service.dart`
|
|||
|
|
- `apps/lib/features/calendar/data/services/calendar_repository.dart`
|
|||
|
|
- `apps/lib/features/settings/data/services/settings_user_cache.dart`
|
|||
|
|
- `apps/lib/features/settings/data/services/user_profile_cache_repository.dart`
|
|||
|
|
- `apps/lib/features/todo/data/todo_repository.dart`
|
|||
|
|
|
|||
|
|
## 状态
|
|||
|
|
|
|||
|
|
- [ ] 待修复
|