# 架构设计文档 ## 核心设计原则 **分层原则:通用组件 vs Provider特定组件** --- ## 📐 架构图 ``` ┌─────────────────────────────────────────┐ │ 通用层 (Universal Layer) │ │ 不调用浏览器特定API,所有Provider共享 │ ├─────────────────────────────────────────┤ │ - WorkflowEngine │ │ - 接口定义 (IAction, ISmartSelector) │ │ - 类型定义 (Types) │ │ - 抽象基类 (BaseAction, BaseProvider) │ └──────────────┬──────────────────────────┘ │ ↓ 依赖接口 ┌─────────────────────────────────────────┐ │ Provider特定层 (Provider Layer) │ │ 调用浏览器特定API,每个Provider独立实现 │ ├─────────────────────────────────────────┤ │ - Actions (click, input, etc.) │ │ - SmartSelector │ │ - ActionFactory │ │ - BrowserProvider │ └─────────────────────────────────────────┘ ``` --- ## 🗂️ 目录结构 ``` src/ ├── core/ # 通用核心层 ✅ │ ├── interfaces/ # 接口定义 │ │ ├── IBrowserProvider.ts # Provider接口 │ │ ├── IAction.ts # Action接口 │ │ └── ISmartSelector.ts # SmartSelector接口 │ ├── base/ # 抽象基类 │ │ ├── BaseBrowserProvider.ts │ │ └── BaseAction.ts │ └── types/ # 类型定义 │ └── index.ts │ ├── workflow/ # 通用工作流 ✅ │ └── WorkflowEngine.ts # 工作流引擎(通用!) │ ├── factory/ # 工厂模式 ✅ │ └── BrowserFactory.ts │ └── providers/ # Provider实现层 ❌ ├── adspower/ # AdsPower (Puppeteer) │ ├── AdsPowerProvider.ts # Provider实现 │ ├── actions/ # AdsPower专用Actions │ │ ├── ClickAction.ts │ │ ├── InputAction.ts │ │ └── ... │ └── core/ # AdsPower专用Core │ ├── SmartSelector.ts # Puppeteer实现 │ └── ActionFactory.ts │ └── playwright/ # Playwright (未来) ├── PlaywrightProvider.ts ├── actions/ # Playwright专用Actions └── core/ ├── SmartSelector.ts # Playwright实现 └── ActionFactory.ts ``` --- ## 📊 组件分类 ### ✅ 通用组件(所有Provider共享) | 组件 | 位置 | 职责 | |------|------|------| | **WorkflowEngine** | `workflow/` | 执行工作流,调用Action接口 | | **接口定义** | `core/interfaces/` | 定义规范(IAction, ISmartSelector等) | | **类型定义** | `core/types/` | 配置、结果等类型 | | **抽象基类** | `core/base/` | 通用实现逻辑 | | **BrowserFactory** | `factory/` | 创建Provider实例 | **特点:** - ✅ 不调用浏览器特定API - ✅ 只依赖接口,不依赖实现 - ✅ 所有Provider可以共享代码 --- ### ❌ Provider特定组件 | 组件 | 位置 | 职责 | 原因 | |------|------|------|------| | **Actions** | `providers/*/actions/` | 执行具体操作 | 需要调用`page.click()`等API | | **SmartSelector** | `providers/*/core/` | 查找元素 | 需要调用`page.waitForSelector()`等 | | **ActionFactory** | `providers/*/core/` | 创建Action实例 | 返回Provider特定的Action类 | | **Provider** | `providers/*/` | 管理浏览器 | 调用Puppeteer/Playwright等API | **特点:** - ❌ 调用浏览器特定API - ❌ 每个Provider独立实现 - ❌ 不能跨Provider共享 --- ## 💡 为什么这样设计? ### WorkflowEngine为什么是通用的? ```typescript // WorkflowEngine只调用接口,不依赖具体实现 class WorkflowEngine { async executeStep(step) { // 从Factory获取Action(多态) const ActionClass = this.actionFactory.getAction(step.action); const action = new ActionClass(step, this.context); // 执行(通过接口调用,不关心Puppeteer还是Playwright) await action.execute(); } } ``` **关键:** 只依赖`IAction`接口,不知道是`PuppeteerClickAction`还是`PlaywrightClickAction`! --- ### SmartSelector为什么是Provider特定的? ```typescript // Puppeteer版本 class PuppeteerSmartSelector { async find(timeout) { return await this.page.waitForSelector(selector, { timeout }); // ↑ Puppeteer特定API } } // Playwright版本(API不同!) class PlaywrightSmartSelector { async find(timeout) { return await this.page.locator(selector).waitFor({ timeout }); // ↑ Playwright特定API } } ``` **关键:** 必须直接调用浏览器API,无法抽象! --- ## 🔄 工作流程 ``` 1. 用户创建Provider ↓ BrowserFactory.create('adspower') 2. WorkflowEngine执行 ↓ new WorkflowEngine(workflow, context, actionFactory) 3. 执行每个步骤 ↓ actionFactory.getAction('click') // 获取AdsPower的ClickAction ↓ action.execute() // 调用Puppeteer API ``` **关键:** WorkflowEngine不知道也不关心是哪个Provider! --- ## ✅ 总结 | 层次 | 组件 | 通用/特定 | 原因 | |------|------|----------|------| | **业务层** | WorkflowEngine | ✅ 通用 | 只调用接口 | | **接口层** | IAction, ISmartSelector | ✅ 通用 | 定义规范 | | **实现层** | Actions, SmartSelector | ❌ Provider特定 | 调用浏览器API | | **基础层** | Provider | ❌ Provider特定 | 管理浏览器 | **设计原则:** - 依赖倒置:上层依赖接口,不依赖实现 - 开闭原则:添加新Provider不修改通用层 - 单一职责:通用层负责流程,Provider层负责实现 --- **创建时间:** 2025-11-21 **状态:** 已修正 ✅