mirror of
https://github.com/linshenkx/prompt-optimizer.git
synced 2026-06-01 04:00:16 +08:00
## 核心架构重构 - 创建IImportExportable接口,定义统一的导入导出规范 - 新增ImportExportError错误类,提供专门的错误处理 - 将导入导出逻辑从集中式DataManager分散到各个服务 - DataManager职责精简:从375行减至67行(-308行),仅负责协调 ## 存储键架构优化 - 移动storage-keys.ts从ui包到core包,实现统一管理 - 修复存储键双重用途问题:物理存储键vs逻辑JSON导出键 - PreferenceService添加'pref:'前缀处理物理存储 - 解决数据导出不完整的关键架构缺陷 ## 服务层改造 ### ModelManager - 实现IImportExportable接口(+209行,-153行) - 添加exportData/importData/validateData方法 - 保持向后兼容的数据格式 ### TemplateManager - 实现分布式导入导出逻辑 - 移除过度设计的configurable storageKey - 统一使用PreferenceService管理用户偏好 ### HistoryManager - 添加完整的导入导出实现 - 支持数据验证和错误处理 ### PreferenceService - 实现统一的用户设置导入导出 - 处理存储键前缀转换逻辑 - 支持builtin-template-language等核心设置 ## Electron桌面端更新 - main.js: 新增148行IPC处理逻辑 - preload.js: 新增177行API暴露 - 更新所有service proxy类支持新接口 - 保持IPC通信的类型安全 ## 测试体系完善 - 新增各服务专门的import-export.test.ts文件 - 创建data/import-export-integration.test.ts集成测试 - 建立AI自动化测试框架验证存储键一致性 - 更新现有测试适配新架构 ## 文档与架构说明 - 创建import-export-interface-design.md设计文档 - 添加storage-key-architecture.md架构说明 - 建立AI自动化测试文档体系 - 更新workspace文档记录重构过程 BREAKING CHANGE: 导入导出接口从集中式DataManager重构为分布式服务实现, 各服务现在必须实现IImportExportable接口,存储键架构发生变化
7.0 KiB
7.0 KiB
存储架构重构总结
📋 重构概述
基于用户反馈,我们对存储架构进行了两项重要改进:
- 移除TemplateManager的过度设计 - 删除不必要的storageKey配置
- 统一使用PreferenceService - 将所有用户偏好设置统一管理
🎯 改进1:移除TemplateManager的过度设计
问题分析
TemplateManager的config?.storageKey是过度设计的产物:
- 理论上提供灵活性,但实际从未被使用
- 增加了不必要的复杂性
- 所有地方都使用默认值,没有传入自定义storageKey
修改内容
1. 简化TemplateManagerConfig接口
// ❌ 修改前
export interface TemplateManagerConfig {
storageKey?: string; // localStorage存储键名
cacheTimeout?: number; // 缓存超时时间
}
// ✅ 修改后
export interface TemplateManagerConfig {
cacheTimeout?: number; // 缓存超时时间
}
2. 直接使用常量
// ❌ 修改前
this.config = {
storageKey: config?.storageKey || CORE_SERVICE_KEYS.USER_TEMPLATES,
cacheTimeout: config?.cacheTimeout || 5 * 60 * 1000,
};
// ✅ 修改后
this.config = {
cacheTimeout: config?.cacheTimeout || 5 * 60 * 1000,
};
// 直接使用常量
await this.storageProvider.setItem(CORE_SERVICE_KEYS.USER_TEMPLATES, data);
优势
- 简化代码 - 减少不必要的配置选项
- 提高可读性 - 直接使用常量,意图更明确
- 减少维护成本 - 少一个配置点,少一个出错的可能
🎯 改进2:统一使用PreferenceService
问题分析
内置模板语言设置与其他UI设置使用不同的存储方式:
- 其他UI设置通过PreferenceService存储(带
pref:前缀) - 内置模板语言直接存储(无前缀)
- 导致存储方式不一致,增加了DataManager的复杂性
架构原则重新审视
用户的观点是正确的:
- PreferenceService不仅仅是UI设置 - 它是用户偏好设置的统一管理
- 内置模板语言也是用户偏好 - 用户选择使用中文还是英文模板
- 统一存储方式更简洁 - 减少特殊情况处理
修改内容
1. TemplateLanguageService使用PreferenceService
// ❌ 修改前
export class TemplateLanguageService {
private readonly STORAGE_KEY = 'app:settings:ui:builtin-template-language';
private storage: IStorageProvider;
constructor(storage: IStorageProvider) {
this.storage = storage;
}
async setLanguage(language: BuiltinTemplateLanguage): Promise<void> {
await this.storage.setItem(this.STORAGE_KEY, language);
}
}
// ✅ 修改后
export class TemplateLanguageService {
private storage: IStorageProvider;
private preferenceService: IPreferenceService;
constructor(storage: IStorageProvider, preferenceService: IPreferenceService) {
this.storage = storage;
this.preferenceService = preferenceService;
}
async setLanguage(language: BuiltinTemplateLanguage): Promise<void> {
await this.preferenceService.set(UI_SETTINGS_KEYS.BUILTIN_TEMPLATE_LANGUAGE, language);
}
}
2. 更新工厂函数
// ❌ 修改前
export function createTemplateLanguageService(storageProvider: IStorageProvider): TemplateLanguageService {
return new TemplateLanguageService(storageProvider);
}
// ✅ 修改后
export function createTemplateLanguageService(
storageProvider: IStorageProvider,
preferenceService: IPreferenceService
): TemplateLanguageService {
return new TemplateLanguageService(storageProvider, preferenceService);
}
3. 简化DataManager
// ❌ 修改前
const PREFERENCE_BASED_KEYS = [
'app:settings:ui:theme-id',
'app:settings:ui:preferred-language',
// ...
] as const;
const DIRECT_STORAGE_KEYS = [
'app:settings:ui:builtin-template-language', // 特殊处理
] as const;
// ✅ 修改后
const PREFERENCE_BASED_KEYS = [
'app:settings:ui:theme-id',
'app:settings:ui:preferred-language',
'app:settings:ui:builtin-template-language', // 统一处理
// ...
] as const;
const DIRECT_STORAGE_KEYS = [
// 现在所有UI设置都通过PreferenceService存储
] as const;
优势
- 架构一致性 - 所有用户偏好设置都通过PreferenceService管理
- 简化DataManager - 不再需要区分两种存储方式
- 语义清晰 - 内置模板语言确实是用户偏好,应该统一管理
- 便于扩展 - 未来新增用户偏好设置都遵循同一模式
📊 影响范围
修改的文件
-
核心服务
packages/core/src/services/template/types.ts- 简化配置接口packages/core/src/services/template/manager.ts- 移除storageKey配置packages/core/src/services/template/languageService.ts- 使用PreferenceServicepackages/core/src/services/data/manager.ts- 简化存储键分类
-
应用初始化
packages/ui/src/composables/useAppInitializer.ts- 更新服务创建packages/desktop/main.js- 更新服务创建
-
测试文件
packages/core/tests/unit/template/languageService.test.ts- 更新测试packages/core/tests/unit/template/manager.test.ts- 更新测试
-
文档
docs/architecture/storage-key-architecture.md- 更新架构说明
向后兼容性
- 数据导入 - 旧版本数据仍然可以正常导入
- 键名转换 - LEGACY_KEY_MAPPING确保兼容性
- 用户体验 - 用户不会感知到任何变化
🎉 重构效果
代码质量提升
- 减少复杂性 - 移除不必要的配置选项
- 提高一致性 - 统一的存储方式
- 增强可维护性 - 更简洁的架构
架构改进
- 职责清晰 - PreferenceService专门管理用户偏好
- 扩展性好 - 新增用户偏好设置有明确的模式
- 测试友好 - 统一的存储方式便于测试
用户体验
- 功能不变 - 用户不会感知到任何变化
- 数据安全 - 完全向后兼容,不会丢失数据
- 性能提升 - 减少了特殊情况处理的开销
🚀 最佳实践
1. 新增用户偏好设置
// 1. 在常量文件中定义键名
export const UI_SETTINGS_KEYS = {
NEW_PREFERENCE: 'app:settings:ui:new-preference',
} as const;
// 2. 通过PreferenceService存储
await preferenceService.set(UI_SETTINGS_KEYS.NEW_PREFERENCE, value);
// 3. 在DataManager中添加到PREFERENCE_BASED_KEYS
const PREFERENCE_BASED_KEYS = [
// ...existing keys
'app:settings:ui:new-preference',
] as const;
2. 避免过度设计
- 只在真正需要时才添加配置选项
- 优先使用常量而不是可配置参数
- 定期审查和清理不必要的配置
3. 保持架构一致性
- 同类型的数据使用相同的存储方式
- 遵循既定的命名规范
- 保持服务职责的清晰边界
📝 总结
这次重构体现了"简单即美"的设计哲学:
- 移除过度设计 - 删除不必要的复杂性
- 统一架构模式 - 相同类型的数据使用相同的处理方式
- 保持向后兼容 - 在改进架构的同时不影响用户
重构后的架构更加简洁、一致和可维护,为未来的功能扩展奠定了良好的基础。