# 三层架构重构 + 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 个命令,职责混乱)** ```bash jclean create / list / status # 任务管理 jclean run # 工作流推进 jclean process / reprocess / merge # 中间层细粒度控制(混淆) jclean clear ```text **问题**: - `run` vs `process`/`merge` 边界不清 - 用户困惑:"什么时候用 run,什么时候用 process?" ### **精简后(5 个命令,职责清晰)** ```bash jclean create --source [options] # 创建任务 jclean list # 列举任务 jclean status # 查看状态 jclean run [--bucket ] # 统一推进(自动/重跑) jclean clear # 清空单批 ```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` 循环推进到完成(可选) 🚀 项目已就绪,可投入使用!