Refactor yaml2pptx.py from a 1,245-line monolithic script into a modular architecture with clear separation of concerns. The entry point is now 127 lines, with business logic distributed across focused modules. Architecture: - core/: Domain models (elements, template, presentation) - loaders/: YAML loading and validation - renderers/: PPTX and HTML rendering - preview/: Flask preview server - utils.py: Shared utilities Key improvements: - Element abstraction layer using dataclass with validation - Renderer logic built into generator classes - Single-direction dependencies (no circular imports) - Each module 150-300 lines for better readability - Backward compatible CLI interface Documentation: - README.md: User-facing usage guide - README_DEV.md: Developer documentation OpenSpec: - Archive refactor-yaml2pptx-modular change (63/70 tasks complete) - Sync 5 delta specs to main specs (2 new + 3 updated)
106 lines
3.8 KiB
Markdown
106 lines
3.8 KiB
Markdown
# Modular Architecture
|
||
|
||
## Purpose
|
||
|
||
定义项目的模块化架构规格,确保代码按功能职责组织,模块大小适中,依赖关系清晰,易于维护和扩展。
|
||
|
||
## Requirements
|
||
|
||
### Requirement: 代码必须按功能模块组织
|
||
|
||
系统必须将代码按照功能职责拆分为独立的模块文件,每个模块文件的代码行数应控制在 150-300 行之间,确保代码易于阅读和维护。
|
||
|
||
#### Scenario: 单文件脚本拆分为多个模块
|
||
|
||
- **WHEN** 开发者查看项目结构
|
||
- **THEN** 系统应包含以下模块文件:
|
||
- `yaml2pptx.py`(入口脚本,约 100 行)
|
||
- `core/elements.py`(元素数据类)
|
||
- `core/template.py`(模板系统)
|
||
- `core/presentation.py`(演示文稿类)
|
||
- `loaders/yaml_loader.py`(YAML 加载)
|
||
- `renderers/pptx_renderer.py`(PPTX 渲染器)
|
||
- `renderers/html_renderer.py`(HTML 渲染器)
|
||
- `preview/server.py`(预览服务器)
|
||
- `utils.py`(工具函数)
|
||
|
||
#### Scenario: 每个模块文件大小适中
|
||
|
||
- **WHEN** 开发者打开任意模块文件
|
||
- **THEN** 文件代码行数应在 150-300 行之间(入口脚本除外,约 100 行)
|
||
|
||
### Requirement: 模块必须按层次组织
|
||
|
||
系统必须采用四层架构组织代码:入口层(yaml2pptx.py)、核心层(core/)、加载层(loaders/)、渲染层(renderers/)、预览层(preview/),每层职责清晰。
|
||
|
||
#### Scenario: 核心层包含领域模型
|
||
|
||
- **WHEN** 开发者查看 core/ 目录
|
||
- **THEN** 应包含元素数据类(elements.py)、模板系统(template.py)、演示文稿类(presentation.py)
|
||
|
||
#### Scenario: 加载层负责数据输入
|
||
|
||
- **WHEN** 开发者查看 loaders/ 目录
|
||
- **THEN** 应包含 YAML 加载和验证逻辑(yaml_loader.py)
|
||
|
||
#### Scenario: 渲染层负责数据输出
|
||
|
||
- **WHEN** 开发者查看 renderers/ 目录
|
||
- **THEN** 应包含 PPTX 渲染器(pptx_renderer.py)和 HTML 渲染器(html_renderer.py)
|
||
|
||
#### Scenario: 预览层提供可选功能
|
||
|
||
- **WHEN** 开发者查看 preview/ 目录
|
||
- **THEN** 应包含 Flask 服务器和文件监听逻辑(server.py)
|
||
|
||
### Requirement: 模块间依赖关系必须清晰
|
||
|
||
系统必须保持清晰的依赖方向:入口层 → 渲染层 → 核心层 ← 加载层,避免循环依赖。
|
||
|
||
#### Scenario: 依赖方向单向流动
|
||
|
||
- **WHEN** 开发者分析模块导入关系
|
||
- **THEN** 依赖关系应为:
|
||
- yaml2pptx.py 导入 renderers、loaders、core、preview
|
||
- renderers 导入 core
|
||
- loaders 导入 core
|
||
- core 不导入其他业务模块(只导入标准库和第三方库)
|
||
- preview 导入 renderers 和 core
|
||
|
||
#### Scenario: 不存在循环依赖
|
||
|
||
- **WHEN** 开发者运行脚本
|
||
- **THEN** 系统不应出现循环导入错误
|
||
|
||
### Requirement: 入口脚本必须保持单一职责
|
||
|
||
yaml2pptx.py 必须仅包含 CLI 参数解析和主流程编排,所有业务逻辑应委托给相应的模块。
|
||
|
||
#### Scenario: 入口脚本只负责 CLI 和流程编排
|
||
|
||
- **WHEN** 开发者查看 yaml2pptx.py
|
||
- **THEN** 文件应仅包含:
|
||
- `/// script` 依赖声明
|
||
- `parse_args()` 函数(CLI 参数解析)
|
||
- `main()` 函数(流程编排)
|
||
- 必要的导入语句
|
||
|
||
#### Scenario: 入口脚本代码行数精简
|
||
|
||
- **WHEN** 开发者统计 yaml2pptx.py 的代码行数
|
||
- **THEN** 应约为 100 行(不包括注释和空行)
|
||
|
||
### Requirement: 保持向后兼容的使用方式
|
||
|
||
系统必须保持 `uv run yaml2pptx.py` 的使用方式不变,用户无需修改现有的调用方式。
|
||
|
||
#### Scenario: CLI 使用方式不变
|
||
|
||
- **WHEN** 用户运行 `uv run yaml2pptx.py input.yaml output.pptx`
|
||
- **THEN** 系统应正常生成 PPTX 文件,行为与重构前一致
|
||
|
||
#### Scenario: CLI 参数保持兼容
|
||
|
||
- **WHEN** 用户使用 `--template-dir`、`--preview`、`--port` 等参数
|
||
- **THEN** 系统应正确解析并执行相应功能
|