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`
|
||
|
||
## 状态
|
||
|
||
- [ ] 待修复
|