auto-account-machine/browser-automation-ts/TOOL-V2-DESIGN.md
2025-11-21 17:59:49 +08:00

196 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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<IGeneratorService>('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<IStorageService>('storage');
}
}
```
### 2. 任意组合
```typescript
// 组合1MySQL + 本地卡生成器
toolManager.register(new MySQLStorageTool());
toolManager.register(new LocalCardGenerator());
// 组合2Redis + 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<void> {
// 一键初始化所有工具
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等通信而不是硬编码依赖关系**