# Tool V2 - 可拼接式设计 ## 🎯 设计理念 ### 核心原则 1. **松耦合** - 工具之间通过接口通信,不直接依赖 2. **可替换** - 任何工具都可以被同类工具替换 3. **可组合** - 像乐高一样自由组合 4. **依赖注入** - 通过服务名获取依赖,而非硬编码 --- ## 📦 架构示意图 ``` ┌─────────────────────────────────────────┐ │ IToolContext (上下文) │ │ ┌─────────────┐ ┌───────────────┐ │ │ │ Data Store │ │ Service Bus │ │ │ └─────────────┘ └───────────────┘ │ └─────────────────────────────────────────┘ ↑ ↑ │ │ ┌────────┴────────┬───────┴────────┐ │ │ │ ┌─────────┐ ┌──────────┐ ┌──────────┐ │ Tool A │ │ Tool B │ │ Tool C │ │provides │ │requires │ │provides │ │storage │ │storage │ │generator │ └─────────┘ └──────────┘ └──────────┘ ``` --- ## 💡 使用示例 ### 场景1:使用MySQL存储 ```typescript const toolManager = new ToolManager(); // 注册工具(顺序无关!) toolManager.register(new CardGeneratorTool()); toolManager.register(new MySQLStorageTool()); // 提供storage toolManager.register(new AccountGeneratorTool()); // 自动解决依赖并初始化 await toolManager.initializeAll(); // 使用 const context = toolManager.getContext(); const cardGen = context.getService('card-generator'); const card = await cardGen.generate(); ``` ### 场景2:切换到Redis存储(只需改一行!) ```typescript const toolManager = new ToolManager(); toolManager.register(new CardGeneratorTool()); toolManager.register(new RedisStorageTool()); // 替换成Redis! toolManager.register(new AccountGeneratorTool()); await toolManager.initializeAll(); // 其他代码完全不用改 ``` --- ## 🔌 可拼接的优势 ### 1. 完全解耦 ```typescript // ❌ 旧设计 - 耦合 class CardGenerator { constructor(private db: MySQLDatabase) {} // 硬编码依赖MySQL } // ✅ 新设计 - 解耦 class CardGeneratorTool { readonly requires = ['storage']; // 只声明需要storage接口 async initialize(context: IToolContext) { // 不关心谁提供storage,只要符合IStorageService接口即可 const storage = context.getService('storage'); } } ``` ### 2. 任意组合 ```typescript // 组合1:MySQL + 本地卡生成器 toolManager.register(new MySQLStorageTool()); toolManager.register(new LocalCardGenerator()); // 组合2:Redis + API卡生成器 toolManager.register(new RedisStorageTool()); toolManager.register(new APICardGenerator()); // 组合3:内存存储 + 测试卡生成器(用于测试) toolManager.register(new MemoryStorageTool()); toolManager.register(new MockCardGenerator()); ``` ### 3. 插件化 ```typescript // 添加新功能,完全不影响现有工具 toolManager.register(new LoggerTool()); // 日志工具 toolManager.register(new MetricsTool()); // 监控工具 toolManager.register(new CacheTool()); // 缓存工具 ``` --- ## 🏗️ 在Adapter中使用 ### windsurf-adapter.ts ```typescript import { ToolManager } from '../../src/tools/ToolManager'; import { AccountGeneratorTool } from '../../src/tools/AccountGeneratorTool'; import { CardGeneratorTool } from '../../src/tools/CardGeneratorTool'; import { MySQLStorageTool } from '../../src/tools/MySQLStorageTool'; class WindsurfAdapter implements ISiteAdapter { private toolManager: ToolManager; constructor() { this.toolManager = new ToolManager(); // 拼接需要的工具(像搭积木) this.toolManager.register(new MySQLStorageTool()); this.toolManager.register(new AccountGeneratorTool()); this.toolManager.register(new CardGeneratorTool()); // 想要更多功能?继续注册! // this.toolManager.register(new EmailHandlerTool()); // this.toolManager.register(new CaptchaSolverTool()); } async initialize(context: any): Promise { // 一键初始化所有工具 await this.toolManager.initializeAll(); const toolContext = this.toolManager.getContext(); // 生成账号 if (!context.data.account?.email) { const accountGen = toolContext.getService('account-generator'); context.data.account = await accountGen.generate(); } } getHandlers() { const toolContext = this.toolManager.getContext(); return { generateCard: async () => { const cardGen = toolContext.getService('card-generator'); return await cardGen.generate(); }, saveToDatabase: async () => { const storage = toolContext.getService('storage'); await storage.save('account:xxx', this.context.data.account); } }; } } ``` --- ## ✅ 对比总结 | 特性 | V1设计 | V2设计 | |------|--------|--------| | **耦合度** | 高(直接依赖) | 低(接口依赖) | | **可替换** | 难(需改代码) | 易(改配置) | | **测试** | 难(需mock具体类) | 易(mock接口) | | **扩展** | 难(需修改现有代码) | 易(只需添加工具) | | **维护** | 难(改一处影响多处) | 易(工具独立) | --- ## 🎉 这才是真正的"可拼接"! 就像: - **USB接口** - 不管是键盘、鼠标、U盘,只要符合USB规范就能插上 - **乐高积木** - 不同的积木可以自由组合 - **插座** - 不管什么电器,只要符合电压规范就能用 **工具之间通过标准接口(storage、generator、validator等)通信,而不是硬编码依赖关系!**