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

6.5 KiB
Raw Blame History

架构设计文档

核心设计原则

分层原则:通用组件 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为什么是通用的

// 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特定的

// 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
状态: 已修正