Files
social-app/docs/bugs/服务层与Repository层职责混乱.md
T

124 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 服务层与 Repository 层职责混乱
## 问题描述
当前 `CalendarService``SettingsUserCache``UserProfileCacheRepository` 等服务/仓库职责边界模糊,存在大量重复逻辑和不必要的封装。
## 问题1SettingsUserCache 不该存在
### 当前结构
```
SettingsUserCache UserProfileCacheRepository
┌─────────────────┐ ┌─────────────────────────┐
│ - _cachedUser │ ←→ │ - HybridCacheStore │
│ - getProfile() │ │ - CachePolicy │
│ - set() │ │ - getProfile() │
│ - invalidate() │ │ - setCached() │
└─────────────────┘ └─────────────────────────┘
```
### 问题
- `SettingsUserCache` 只是给 `UserProfileCacheRepository` 包了一层内存缓存
- 两者的 `getProfile()``invalidate()` 逻辑几乎相同
- 这是重复包装,应该合并
## 问题2Repository 缓存逻辑重复
### 涉及文件
- `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;
}
```
## 问题3CalendarService 不必要的延迟初始化
```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`
## 状态
- [ ] 待修复