背景
随着项目架构演进,部分早期设计的抽象层和事件机制变得冗余。这些代码不仅增加了维护成本,还可能导致新开发者产生困惑。本次清理旨在移除不再使用的代码,简化项目结构。
一、删除的文件与模块
1. AppEventBus 事件总线 (event_bus.dart)
原设计
/// 应用生命周期阶段
enum AppLifecyclePhase {
idle,
loadingConfig,
startingCore,
checkingNetwork,
authenticating,
loadingData,
ready,
error,
}
/// 应用事件类型
enum AppEventType {
configLoaded,
coreStarted,
networkStatusChanged,
authStateChanged,
dataLoaded,
appReady,
// ...
}
class AppEventBus {
// 生命周期管理
void setPhase(AppLifecyclePhase phase) { ... }
StreamSubscription<AppLifecyclePhase> onPhaseChange(...) { ... }
Future<void> waitUntilReady({Duration timeout}) { ... }
// 事件发布/订阅
void emit(AppEventType type, {dynamic data}) { ... }
StreamSubscription<AppEvent> subscribe(...) { ... }
StreamSubscription<AppEvent> on(AppEventType type, ...) { ... }
}删除原因
- 与 Provider 状态管理重复 - AppState 已通过
notifyListeners()提供状态变化通知 - 增加系统复杂度 - 事件总线引入了额外的事件流和订阅管理
- 实际使用率低 - 大部分组件直接使用
context.watch<AppState>() - 调试困难 - 事件流难以追踪,不如直接的状态变化直观
清理范围
- 删除
lib/core/event_bus.dart文件(约 200 行) - 移除 AppState 中所有
eventBus.emit()调用 - 移除 AppState 中
eventBus.setPhase()调用 - 移除 main.dart 中
eventBus引用
2. ICoreService 抽象接口 (core_service.dart)
原设计
/// 核心服务抽象接口
///
/// 定义所有核心操作的接口,支持不同实现:
/// - [HttpCoreService]: 通过 HTTP 调用 Go 服务
/// - [NativeCoreService]: 通过 FFI 直接调用 Go 库
abstract class ICoreService {
Future<bool> healthCheck();
Future<CoreResult<String>> initPassword(String password);
Future<CoreResult<String>> unlockVault(String password);
Future<CoreResult<MetadataIndex>> getMetadata();
Future<CoreResult<void>> syncMetadata(MetadataIndex metadata);
Future<CoreResult<FileMetadata>> uploadFile({...});
Future<CoreResult<List<int>>> downloadFile(String fileId);
Future<CoreResult<void>> deleteFile(String fileId);
String getStreamUrl(String fileId);
Map<String, String> getStreamHeaders();
Future<CoreResult<List<FileInfo>>> listFiles();
}删除原因
- 接口与实际调用分离 - 实际代码中直接使用
ApiClient,没有通过ICoreService接口 - 过度抽象 - 设计之初考虑了 HTTP 和 FFI 两种实现,但实际只使用 HTTP
- 维护负担 - 接口需要与 ApiClient 保持同步,增加维护成本
3. HttpCoreService 实现 (http_core_service.dart)
原设计
class HttpCoreService implements ICoreService {
final String baseUrl;
late final Dio _dio;
@override
Future<bool> healthCheck() async { ... }
@override
Future<CoreResult<String>> unlockVault(String password) async { ... }
// ... 其他方法实现
}删除原因
- 从未被使用 - 代码中直接使用
ApiClient,HttpCoreService 只是死代码 - 与 ApiClient 功能重复 - 两者都封装了对 Go 核心的 HTTP 调用
- 增加混乱 - 新开发者可能困惑应该使用哪个
4. NativeCoreService 简化
原状态
class NativeCoreService implements ICoreService {
// 大量未实现的方法,抛出 UnimplementedError
@override
Future<bool> healthCheck() {
throw UnimplementedError();
}
// ...
}简化后
class NativeCoreService {
static bool _isRunning = false;
static Process? _coreProcess;
/// 启动嵌入式核心(桌面端)
static Future<void> startEmbeddedCore({
required int port,
String? configPath,
}) async { ... }
/// 停止嵌入式核心
static Future<void> stopEmbeddedCore() async { ... }
/// 是否正在运行
static bool get isRunning => _isRunning;
}- 移除
implements ICoreService - 只保留桌面端核心进程管理功能
- 代码从约 80 行减少到约 40 行
二、清理过程
第一步:识别死代码
通过全局搜索确认以下类/文件未被引用:
event_bus.dart- 仅在 app_state.dart 中有引用core_service.dart- 无实际使用http_core_service.dart- 无实际使用
第二步:移除事件总线引用
// app_state.dart - 移除前
import 'event_bus.dart';
class AppState extends ChangeNotifier {
final eventBus = AppEventBus();
Future<void> init() async {
eventBus.setPhase(AppLifecyclePhase.loadingConfig);
// ...
eventBus.emit(AppEventType.appReady);
}
}
// app_state.dart - 移除后
class AppState extends ChangeNotifier {
Future<void> init() async {
// 直接执行初始化逻辑
// 状态变化通过 notifyListeners() 通知
}
}第三步:删除文件
删除的文件:- client/lib/core/event_bus.dart (~200 行)- client/lib/core/services/core_service.dart (~70 行)- client/lib/core/services/http_core_service.dart (~260 行)
简化的文件:- client/lib/core/services/native_core_service.dart (-40 行)第四步:验证
flutter analyze
# No issues found!三、代码变化统计
| 操作 | 文件 | 行数变化 |
|---|---|---|
| 删除 | event_bus.dart | -200 |
| 删除 | core_service.dart | -70 |
| 删除 | http_core_service.dart | -260 |
| 简化 | native_core_service.dart | -40 |
| 清理引用 | app_state.dart | -15 |
| 清理引用 | main.dart | -5 |
| 总计 | -590 行 |
四、架构简化对比
清理前
AppState├── eventBus: AppEventBus # 事件总线(冗余)├── api: ApiClient # HTTP 客户端└── 其他状态...
ICoreService (抽象接口)├── HttpCoreService # HTTP 实现(死代码)└── NativeCoreService # FFI 实现(过度设计)清理后
AppState├── api: ApiClient # 直接使用 HTTP 客户端└── 其他状态...
NativeCoreService # 仅保留桌面端核心进程管理├── startEmbeddedCore()├── stopEmbeddedCore()└── isRunning五、经验教训
1. 避免过早抽象
“不要为了未来可能的需求而过度设计”
ICoreService 接口设计之初是为了支持 HTTP 和 FFI 两种调用方式。但实际上:
- HTTP 方式已经足够满足需求
- FFI 方式从未实现
- 接口增加了维护成本
2. Provider 已足够
在使用 Provider 状态管理的项目中,不需要额外引入事件总线:
notifyListeners()提供状态变化通知context.watch<AppState>()实现 UI 响应- 状态变化直观可追踪
3. 定期清理死代码
随着项目演进,一些早期设计会变得过时。定期清理可以:
- 减少代码量,降低维护成本
- 避免新开发者困惑
- 保持代码库健康
总结
本次清理移除了约 590 行无用代码,包括:
- AppEventBus - 与 Provider 状态管理重复的事件总线
- ICoreService - 过度抽象的接口层
- HttpCoreService - 从未使用的死代码
- NativeCoreService 简化 - 仅保留核心功能
清理后代码结构更简洁,职责更清晰:
ApiClient负责所有 HTTP 通信AppState负责全局状态管理NativeCoreService仅负责桌面端核心进程管理