# 架构设计文档

## 核心设计原则

**分层原则：通用组件 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  
**状态:** 已修正 ✅
