📚 渡口文档库

n160 · /home/joehuang

🏠 首页

MasterPlan Services 层架构优化分析

生成时间: 2025-05-28
分析目录: ~/masterplan/lib/services/


一、整体架构概览

1.1 目录结构

lib/services/
├── database/           # 数据库层 (4 files)
├── export/             # 导出服务 (1 file)
├── notification/       # 通知服务 (1 file)
├── repository/         # Repository模式 (8 files)
├── storage/            # 存储层 (4 files)
├── streams/           # 流服务 (1 file)
├── sync/              # 同步服务 (14 files)
│   └── providers/     # 同步提供者 (13 files)
└── task_service/      # TaskService Mixins (9 files)

1.2 核心统计


二、重复代码问题 (Duplication Issues)

2.1 TaskRepository 接口重复 (Critical)

问题: 存在 5 个相互冲突的 TaskRepository 定义

文件路径 类型 行数 问题
lib/services/task_repository.dart abstract class 14 基础接口,分离在根目录
lib/services/task_repository_impl.dart implements TaskRepository 97 Impl在根目录,与interface分离
lib/services/repository/task_repository.dart abstract class 99 完整接口,extends BaseRepository
lib/services/repository/task_repository_impl.dart implements TaskRepository 298 Repository模式实现
lib/services/repository/on_demand_task_repository.dart class 284 按需加载变体
lib/services/repository/task_repository_v2.dart class - 废弃别名指向OnDemandTaskRepository
lib/services/storage/task_repository.dart class - 存储层实现
lib/services/priority_task_repository.dart abstract class - 扩展的优先级接口

影响:
- 代码维护困难,多个接口版本导致决策瘫痪
- 新开发者不清楚应该使用哪个版本
- TaskRepositoryImpl 存在于两个位置 (根目录和 repository/)

// 根目录版本
abstract class TaskRepository {
  Future<List<Task>> getAllTasks();
  Future<List<Task>> getTasksByType(TaskType type);
  // ... 14行
}

// repository/ 版本 - 更完整但命名冲突
abstract class TaskRepository extends BaseRepository<Task> {
  // ... 99行,包含更多方法
}

2.2 SyncProvider 重复实现 (Critical)

问题: 13个 SyncProvider 实现,代码高度重复

providers/
├── firebase_sync_provider.dart          (702行)
├── supabase_sync_provider.dart          (1005行)
├── postgres_sync_provider.dart
├── mongodb_sync_provider.dart
├── google_drive_sync_provider.dart
├── google_drive_provider.dart          (重复命名)
├── onedrive_sync_provider.dart
├── onedrive_provider.dart              (重复命名)
├── dropbox_provider.dart
├── webdav_provider.dart
├── icloud_sync_provider.dart
├── baidu_drive_sync_provider.dart
└── local_sync_provider.dart

重复代码模式:

// 每个Provider都有相同的模板代码
class XxxSyncProvider implements SyncProvider {
  final _connectionStateController = StreamController<bool>.broadcast();
  final _syncStatusController = StreamController<SyncStatus>.broadcast();
  final _realtimeChangeController = StreamController<Map<String, dynamic>>.broadcast();

  @override
  Future<void> initialize() async { /* 几乎相同逻辑 */ }

  @override
  Future<void> authenticate() async { /* 几乎相同逻辑 */ }

  @override
  Future<bool> isAuthenticated() async { /* 几乎相同逻辑 */ }

  @override
  Future<void> uploadData(Map<String, dynamic> data) async { /* Provider特定 */ }

  @override
  Future<Map<String, dynamic>?> downloadData() async { /* Provider特定 */ }
}

重复率估算: ~60-70% 的代码在各Provider间重复

2.3 BaseRepository/CachedRepository 重复

位置: lib/services/repository/base_repository.dart

abstract class BaseRepository<T> {
  Future<List<T>> getAll();
  Future<T?> getById(String id);
  Future<void> add(T item);
  Future<void> update(T item);
  Future<void> delete(String id);
  Future<void> refresh();
}

abstract class CachedRepository<T> extends BaseRepository<T> {
  List<T> _cache = [];
  int _cacheVersion = 0;
  DateTime? _lastUpdated;
  // ... 缓存方法
}

abstract class DataSyncRepository<T> extends CachedRepository<T> {
  Future<void> sync();
  Future<bool> checkSyncStatus();
  Future<void> resolveConflicts();
}

三、架构问题 (Architecture Issues)

3.1 循环依赖风险 (High)

TaskService 
  ↓ (依赖)
TaskRepositoryImpl
  ↓ (依赖)
TaskService (循环!)

查看 task_repository_impl.dart:

class TaskRepositoryImpl implements TaskRepository {
  final TaskService _taskService;
  TaskRepositoryImpl(this._taskService);  // 依赖TaskService
}

TaskService 的某些方法调用 TaskRepository,但 TaskRepositoryImpl 又包装 TaskService。

3.2 关注点分离混淆 (High)

问题: TaskService 承担过多职责

查看 task_service.dart (6560行):

class TaskService extends ChangeNotifier
    with
        TaskServiceQueryMixin,        // 查询
        TaskServiceHierarchyMixin,    // 层级
        TaskServiceStateMixin,        // 状态
        TaskServiceBatchOperationsMixin, // 批量操作
        TaskServiceCRUDMixin,        // CRUD
        TaskServiceFilterMixin,       // 过滤
        TaskServicePriorityMixin,     // 优先级
        TaskServiceFocusMixin {       // 聚焦

  // 混合了大量属性
  final TaskHierarchyManager _hierarchyManager;
  final HasChildrenManager _hasChildrenManager;
  late final TaskTreeOperationService _treeOperationService;
  late final TaskTreeOperationsService _treeOpsService;
  final TaskSnapshotManager _snapshotManager;
  late final LayeredTaskCache _layeredCache;
  CachePerformanceAnalyzer get cacheAnalyzer => CachePerformanceAnalyzer();
}

3.3 服务定位器耦合 (Medium)

task_service.dart 中直接使用 GetIt:

TaskService.internal({String? instanceId})
    : _database = SQLiteDatabaseService.instance,
      _settingsService = GetIt.instance<SettingsService>(),
      _taskFilterService = GetIt.instance<TaskFilterService>(),

3.4 命名混乱 (Medium)

SyncProvider 重复命名:
- GoogleDriveProvider vs GoogleDriveSyncProvider
- OneDriveProvider vs OneDriveSyncProvider

TaskRepository 分散:
- /services/task_repository.dart (根目录)
- /services/repository/task_repository.dart (子目录)
- /services/task_repository_impl.dart (根目录)
- /services/repository/task_repository_impl.dart (子目录)


四、具体重复代码示例

4.1 SyncProvider 模板重复

Firebase 实现 (~line 41-65):

@override
Future<void> initialize() async {
  try {
    await _ensureFirebaseInitialized();
    if (_auth != null) {
      _auth!.authStateChanges().listen((User? user) {
        _connectionStateController.add(user != null);
      });
      _connectionStateController.add(_auth!.currentUser != null);
    } else {
      _connectionStateController.add(false);
    }
  } catch (e) {
    _connectionStateController.add(false);
  }
}

Supabase 实现 (~类似结构):

@override
Future<void> initialize() async {
  // 大约 60 行几乎相同结构的代码
}

4.2 Repository 查询逻辑重复

// task_repository_impl.dart (根目录)
@override
Future<List<Task>> getFocusedTasks() async {
  final tasks = _taskService.allTasks;
  final focusedTasks = tasks.where((task) => 
    task.isFocused && 
    !task.isPriority &&
    !task.isDeleted &&
    task.status != TaskStatus.completed && 
    task.status != TaskStatus.archived
  ).toList();
  final settingsService = GetIt.instance<SettingsService>();
  TaskSortUtil.sortTasksByPreset(focusedTasks, settingsService);
  return focusedTasks;
}

// repository/task_repository_impl.dart 中有几乎完全相同的代码

五、文件散落问题

5.1 相关文件分散

Task 层级维护相关 - 3个服务处理相似功能:
- task_tree_operation_service.dart
- task_tree_operations_service.dart (注意命名差异)
- task_hierarchy_maintenance_service.dart

任务修复相关 - 分散在多个目录:
- task_level_repair_service.dart
- task_data_repair_service.dart
- task_level_diagnostic_service.dart
- task_data_validation_service.dart

5.2 快照管理重复


六、推荐的优化方案

6.1 统一 Repository 接口 (Priority: Critical)

建议: 合并为单一 TaskRepository 接口

// lib/services/task_repository.dart (统一)
abstract class TaskRepository {
  // Core CRUD
  Future<List<Task>> getAllTasks();
  Future<Task?> getTask(String id);
  Future<String> createTask(Task task);
  Future<void> updateTask(Task task);
  Future<void> deleteTask(String id);

  // Query methods
  Future<List<Task>> getTasksByDate(DateTime date);
  Future<List<Task>> getPriorityTasks();
  Future<List<Task>> getFocusedTasks();
  Future<List<Task>> searchTasks(String query);

  // Hierarchy
  Future<List<Task>> getSubTasks(String parentId);
  Future<List<Task>> getAncestors(String taskId);

  // Persistence
  Future<void> refresh();
}

6.2 创建 SyncProvider 抽象基类 (Priority: Critical)

// lib/services/sync/sync_provider_base.dart
abstract class BaseSyncProvider implements SyncProvider {
  // 通用实现
  StreamController<bool> get connectionStateController;
  StreamController<SyncStatus> get syncStatusController;

  Future<void> _initializeBase();
  Future<bool> _checkAuthentication();
}

// Provider特定实现只需覆盖:
abstract class CloudSyncProvider extends BaseSyncProvider {
  Future<void> uploadToCloud();
  Future<Map<String, dynamic>?> downloadFromCloud();
}

6.3 提取公共 Mixin (Priority: Medium)

// lib/services/mixins/task_query_mixin.dart
mixin TaskQueryHelpers {
  List<Task> filterByStatus(List<Task> tasks, TaskStatus status);
  List<Task> filterByPriority(List<Task> tasks);
  List<Task> filterByDateRange(List<Task> tasks, DateTime start, DateTime end);
}

6.4 服务归类 (Priority: Medium)

lib/services/
├── core/                    # 核心接口定义
│   ├── task_repository.dart
│   ├── sync_provider.dart
│   └── database_service.dart
├── impl/                    # 主要实现
│   ├── task_service.dart
│   ├── sqlite_database_service.dart
│   └── sync_service_impl.dart
├── providers/              # 云同步提供者 (统一管理)
│   ├── firebase_provider.dart
│   ├── supabase_provider.dart
│   └── ... (减少重复)
├── repository/             # 仅保留数据访问
│   └── task_repository_impl.dart
└── utils/                  # 辅助服务
    ├── hierarchy/
    └── snapshot/

七、优先级建议

优先级 问题 影响 工作量
P0 TaskRepository 多版本冲突 代码无法维护
P0 SyncProvider 60%+ 重复 任何修改需改13个文件 极高
P1 循环依赖风险 运行时崩溃
P1 TaskService 6500+ 行 单点故障
P2 文件命名混乱 开发效率
P2 服务散落 难以定位

八、总结

lib/services/ 目录存在严重的架构问题:

  1. 重复代码严重: SyncProvider 13个实现共享60%+相同代码
  2. 接口版本冲突: TaskRepository 有5个相互冲突的定义
  3. 文件组织混乱: 100+文件散落在多个子目录,无明确分层
  4. 职责过于集中: TaskService 承担30+职责,6500行代码
  5. 依赖关系复杂: 存在循环依赖和隐性耦合

建议分阶段重构,优先解决 P0 问题以降低维护成本。