清洗管线重构为严格三层架构:
- tango_analyser.py(底层:单词分析)
- task_processor.py(中层:文件 I/O、桶管理)
- workflow.py(顶层:状态机、任务推进)
- 移除旧的 batch_processor.py
新增配置文件系统:
- config.py:TOML 配置,相对路径相对配置文件目录解析
- 查找优先级 --config > cwd > 项目根 > ~ > 默认值
- count=None 语义为处理到文件末尾
项目目录整理:
- 根脚本归档到 scripts/analysis 与 scripts/legacy
- 文档归档到 docs/{design,history,analysis}
- 临时报告移到 reports/(已 gitignore)
文档质量:
- 新增 .markdownlint.json 与 scripts/mdlint.cmd
- 修复全部 14 个 md 文件的 markdownlint 警告
测试:74 passed(8 cleaner + 31 workflow + 6 tango + 15 validator + 14 config)
9.1 KiB
9.1 KiB
三层架构重构 + CLI 精简 - 完成总结
🎉 重构成果
成功将日语词表清洗系统重构为三层架构 + 极简 CLI,职责清晰分离,命令极简易用。
📐 三层架构设计
| 层级 | 模块 | 职责 | 关键接口 |
|---|---|---|---|
| 底层(单词级) | tango_analyser.py |
单词分析:(kanji, kana) → AnalysisResult(状态 + 格式化行) |
TangoAnalyser.analyze() |
| 中间层(文件级) | task_processor.py |
文件 I/O:读源文件 → 调底层 → 按状态分流写桶 | TaskProcessor.process_source() / .process_review() / .merge_final() |
| 工作流层(编排级) | workflow.py |
状态机决策:判断下一步 + 调度中间层 + 更新任务状态 | CleanerWorkflow.run() |
核心原则:
- 底层只返回"状态枚举",不知道文件/桶
- 中间层只负责 I/O,不决策"该做什么"
- 工作流层只做决策,所有文件操作委托给中间层
🎯 CLI 精简(5 个命令)
精简前(7 个命令,职责混乱)
jclean create / list / status # 任务管理
jclean run # 工作流推进
jclean process / reprocess / merge # 中间层细粒度控制(混淆)
jclean clear
```text
**问题**:
- `run` vs `process`/`merge` 边界不清
- 用户困惑:"什么时候用 run,什么时候用 process?"
### **精简后(5 个命令,职责清晰)**
```bash
jclean create <task_id> --source <file> [options] # 创建任务
jclean list # 列举任务
jclean status <task_id> # 查看状态
jclean run <task_id> [--bucket <name>] # 统一推进(自动/重跑)
jclean clear <task_id> # 清空单批
```text
**优势**:
- **统一入口**:`run` 既是自动推进,也是人工重跑的入口
- **语义清晰**:`run` 按流程执行,`--bucket` 指定恢复点
- **学习成本低**:只需记住 `run`,无需理解底层细节
---
## 🚀 典型工作流
```bash
# 1. 创建任务
jclean create batch1 --source data/sources/xinbiaori_1.txt --count 300
# 2. 推进(自动处理源文件 → reviewing/ready)
jclean run batch1
# 输出:有 50 条 review_pinyin 待确认
# 3. 查看状态
jclean status batch1
# 4. 人工修正字典/规则后,重跑指定桶
jclean run batch1 --bucket pinyin
# 5. 继续推进(review 清零 → 自动合并 → merged)
jclean run batch1
# 6. 完成
jclean run batch1
# 输出:completed
```text
**一个命令贯穿全流程**:`run` 自动判断下一步,需要人工时提示,人工完成后继续 `run`。
---
## 📊 代码变更统计
### **新增文件(3 个)**
- `tango_analyser.py` (109 行) — 底层单词分析
- `task_processor.py` (353 行) — 中间层文件处理
- `workflow.py` (240 行) — 工作流编排
### **更新文件**
- `cli.py` (210 行) — 精简到 5 个命令,`run` 统一推进 + 重跑
- `__init__.py` — 导出三层 API,版本 → 0.3.0
- `test_cleaner_workflow.py` (完全重写,31 个测试) — 三层分层测试
- `README_cleaner.md` — 完整更新架构文档
### **删除文件**
- `batch_processor.py` (396 行) — 职责已拆分到三层
---
## ✅ 测试覆盖(60/60 全通过)
```text
============================= 60 passed in 11.66s ==============================
tests/test_cleaner.py 8 passed (底层 Classifier 单元测试)
tests/test_cleaner_workflow.py 31 passed (三层架构集成测试)
- 底层单词分析:7 个参数化词条 → 状态分类
- 中间层文件处理:条数铁律/去重/校验/重跑
- 工作流编排:状态机推进/人工介入门禁
- 任务管理:CRUD/多任务隔离
tests/test_tango.py 6 passed (下游 tango 模型测试)
tests/test_validator.py 15 passed (格式校验测试)
```text
---
## 🎨 API 示例
### **CLI(极简 5 命令)**
```bash
# 自动推进
jclean run batch1
# 人工重跑指定桶(修正字典后)
jclean run batch1 --bucket pinyin
```text
### **工作流层(Python,推荐)**
```python
from pl_japanese.cleaner import CleanerWorkflow, TaskManager
tm = TaskManager()
task = tm.create_task('batch1', source='...', count=300)
wf = CleanerWorkflow(task)
result = wf.run() # 自动推进
if result['action'] == 'need_human':
print(result['review']) # 待确认内容
wf.processor.process_review('pinyin')
wf.run() # 继续推进
```text
### **中间层(Python,精细控制)**
```python
from pl_japanese.cleaner import TaskProcessor
proc = TaskProcessor(task)
proc.process_source() # 处理源文件
proc.process_review('pinyin') # 重跑 review 桶
proc.merge_final(dry_run=True) # 合并校验
```text
### **底层(Python,测试/调试)**
```python
from pl_japanese.cleaner import TangoAnalyser
analyser = TangoAnalyser()
result = analyser.analyze("日本人", "にほんじん")
# result.status == AnalysisStatus.SUCCESS
# result.formatted_line == "日|本|人:に|ほん|じん:ri|ben|ren"
```text
---
## 🔑 关键设计决策
### **1. 底层不返回"桶名",只返回"状态枚举"**
**错误设计**(底层耦合文件分类):
```python
def classify(kanji, kana):
return ("review_pinyin", line) # 底层知道桶名 ❌
```text
**正确设计**(底层只管状态):
```python
def analyze(kanji, kana):
return AnalysisResult(
status=AnalysisStatus.POLYPHONE, # 只返回状态 ✅
formatted_line=line
)
```text
中间层负责映射:`STATUS_TO_BUCKET[AnalysisStatus.POLYPHONE] = "review_pinyin"`
### **2. 中间层不更新任务状态**
**错误设计**(中间层管状态):
```python
def process_source(self):
# ...
self.task.set_status(STATUS_REVIEWING) # 中间层改状态 ❌
```text
**正确设计**(工作流层管状态):
```python
# 中间层只返回统计
def process_source(self):
return {'review_total': 10, ...}
# 工作流层决策状态
def run(self):
result = self.processor.process_source()
if result['review_total'] > 0:
self.task.set_status(STATUS_REVIEWING) # 工作流层改状态 ✅
```text
### **3. CLI 统一到 `run` 命令**
**精简前**:
```bash
jclean process batch1 # 处理源文件
jclean reprocess batch1 --bucket pinyin # 重跑桶
jclean merge batch1 # 合并
```text
**精简后**:
```bash
jclean run batch1 # 自动推进(含 process/merge)
jclean run batch1 --bucket pinyin # 重跑桶(恢复点)
```text
**理由**:
- `run` 自动判断该做什么(process/merge),用户无需关心细节
- `--bucket` 是人工介入的恢复点,语义清晰
- 一个命令贯穿全流程,学习成本最低
---
## 📈 改进对比
| 维度 | 重构前 | 重构后 |
| --- | --- | --- |
| **架构** | BatchProcessor 混合 I/O + 状态管理 | 三层清晰分离 |
| **CLI 命令数** | 7 个(混淆) | 5 个(清晰) |
| **工作流抽象** | 无,需手动调 process/merge | `run()` 一键推进 |
| **测试覆盖** | 部分(25 个) | 完整(60 个,三层分层) |
| **学习成本** | 高(需理解 process/reprocess/merge 区别) | 低(只需记住 `run`) |
| **扩展性** | 低(职责混合) | 高(底层可独立替换) |
---
## 📝 文档更新
- ✅ `README_cleaner.md` — 完整反映三层架构 + 极简 CLI
- ✅ `cli.py` docstring — 更新用法
- ✅ `__init__.py` docstring — 三层说明
- ✅ 所有测试通过(60/60)
---
## 🎓 技术亮点
1. **职责边界清晰**:底层/中间层/工作流层各司其职,单一职责原则
2. **状态与文件解耦**:底层返回枚举,中间层映射文件,解耦干净
3. **工作流抽象**:`run()` 封装决策逻辑,自动/人工/完成三态清晰
4. **CLI 极简**:一个 `run` 命令贯穿全流程,认知负担最低
5. **数据驱动测试**:参数化用例,测试清晰可读
6. **向后兼容**:Python API 保留三层细粒度控制,高级用户不受限
---
## 📦 交付清单
**核心代码**:
- ✅ `src/pl_japanese/cleaner/tango_analyser.py` (新建,109 行)
- ✅ `src/pl_japanese/cleaner/task_processor.py` (新建,353 行)
- ✅ `src/pl_japanese/cleaner/workflow.py` (新建,240 行)
- ✅ `src/pl_japanese/cleaner/cli.py` (精简,210 行)
- ✅ `src/pl_japanese/cleaner/__init__.py` (更新,导出三层 API)
- ✅ `batch_processor.py` (删除,396 行)
**测试**:
- ✅ `tests/test_cleaner_workflow.py` (重写,31 个测试)
- ✅ 60/60 测试全部通过 ✅
**文档**:
- ✅ `README_cleaner.md` (完整更新)
- ✅ 本总结文档
---
## 🎉 总结
三层架构重构 + CLI 精简圆满完成!
**核心成果**:
- **架构清晰**:三层职责分离,可测试/可扩展/可维护
- **CLI 极简**:5 个命令,`run` 统一推进,学习成本最低
- **质量保证**:60 个测试全覆盖,三层分层测试清晰
**下一步**:
- 实际使用新 CLI 处理真实数据
- 根据反馈微调工作流提示信息
- 考虑添加 `jclean run --all` 循环推进到完成(可选)
🚀 项目已就绪,可投入使用!