Back to Prompt Optimizer

存储架构重构总结

docs/architecture/storage-refactoring-summary.md

2.10.27.0 KB
Original Source

存储架构重构总结

📋 重构概述

基于用户反馈,我们对存储架构进行了两项重要改进:

  1. 移除TemplateManager的过度设计 - 删除不必要的storageKey配置
  2. 统一使用PreferenceService - 将所有用户偏好设置统一管理

🎯 改进1:移除TemplateManager的过度设计

问题分析

TemplateManager的config?.storageKey是过度设计的产物:

  • 理论上提供灵活性,但实际从未被使用
  • 增加了不必要的复杂性
  • 所有地方都使用默认值,没有传入自定义storageKey

修改内容

1. 简化TemplateManagerConfig接口

typescript
// ❌ 修改前
export interface TemplateManagerConfig {
  storageKey?: string;     // localStorage存储键名
  cacheTimeout?: number;   // 缓存超时时间
}

// ✅ 修改后
export interface TemplateManagerConfig {
  cacheTimeout?: number;   // 缓存超时时间
}

2. 直接使用常量

typescript
// ❌ 修改前
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

typescript
// ❌ 修改前
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. 更新工厂函数

typescript
// ❌ 修改前
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

typescript
// ❌ 修改前
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 - 不再需要区分两种存储方式
  • 语义清晰 - 内置模板语言确实是用户偏好,应该统一管理
  • 便于扩展 - 未来新增用户偏好设置都遵循同一模式

📊 影响范围

修改的文件

  1. 核心服务

    • packages/core/src/services/template/types.ts - 简化配置接口
    • packages/core/src/services/template/manager.ts - 移除storageKey配置
    • packages/core/src/services/template/languageService.ts - 使用PreferenceService
    • packages/core/src/services/data/manager.ts - 简化存储键分类
  2. 应用初始化

    • packages/ui/src/composables/useAppInitializer.ts - 更新服务创建
    • packages/desktop/main.js - 更新服务创建
  3. 测试文件

    • packages/core/tests/unit/template/languageService.test.ts - 更新测试
    • packages/core/tests/unit/template/manager.test.ts - 更新测试
  4. 文档

    • docs/architecture/storage-key-architecture.md - 更新架构说明

向后兼容性

  • 数据导入 - 旧版本数据仍然可以正常导入
  • 键名转换 - LEGACY_KEY_MAPPING确保兼容性
  • 用户体验 - 用户不会感知到任何变化

🎉 重构效果

代码质量提升

  • 减少复杂性 - 移除不必要的配置选项
  • 提高一致性 - 统一的存储方式
  • 增强可维护性 - 更简洁的架构

架构改进

  • 职责清晰 - PreferenceService专门管理用户偏好
  • 扩展性好 - 新增用户偏好设置有明确的模式
  • 测试友好 - 统一的存储方式便于测试

用户体验

  • 功能不变 - 用户不会感知到任何变化
  • 数据安全 - 完全向后兼容,不会丢失数据
  • 性能提升 - 减少了特殊情况处理的开销

🚀 最佳实践

1. 新增用户偏好设置

typescript
// 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. 保持架构一致性

  • 同类型的数据使用相同的存储方式
  • 遵循既定的命名规范
  • 保持服务职责的清晰边界

📝 总结

这次重构体现了"简单即美"的设计哲学:

  1. 移除过度设计 - 删除不必要的复杂性
  2. 统一架构模式 - 相同类型的数据使用相同的处理方式
  3. 保持向后兼容 - 在改进架构的同时不影响用户

重构后的架构更加简洁、一致和可维护,为未来的功能扩展奠定了良好的基础。