
工程化落地用代码生成器消除重复样板代码一、样板代码的隐性熵增每个新模块都要写一遍 CRUD、DTO、路由注册。结构高度雷同细节稍有出入就出 bug。复制粘贴看似快维护时却要改 N 处。样板代码是典型的该被工具吃掉的工作。它规则明确、产出稳定、几乎不依赖判断。让人手写既浪费又易错。代码生成器解决的就是这个。用模板加元数据一键产出规范骨架。人只填真正需要思考的业务逻辑。本文探讨如何把重复样板工程化用生成器替代手工。二、生成器的核心机制生成器 模板 数据源 渲染引擎。数据源通常是结构化描述如 schema 或注解。模板描述长什么样引擎负责填充。关键在单一来源。元数据只写一次所有产物从它派生。改一处元数据相关文件全部重生成。下面是生成流程flowchart TD A[结构化元数据] -- B[模板引擎加载] B -- C[按规则渲染各文件] C -- D[写入目标路径] D -- E{已有文件?} E --|是| F[仅更新受控区块] E --|否| G[创建新文件] F -- H[完成] G -- H style A fill:#e1f5fe style H fill:#e8f5e9关键在受控区块机制。生成文件里标记// generated区间重生成只覆盖这些区间。手写业务逻辑放在区间外不会被覆盖。这样生成器与人写代码和平共处。三、生产级生成器实现下面用 Python 的jinja2写一个最小生成器。from pathlib import Path from typing import Any from jinja2 import Environment, FileSystemLoader, StrictUndefined MODEL { name: User, fields: [ {name: id, type: int}, {name: name, type: str}, {name: email, type: str}, ], } def render_model(model: dict[str, Any], template_dir: Path) - str: 用严格模式渲染缺变量即报错避免生成半成品 env Environment( loaderFileSystemLoader(str(template_dir)), undefinedStrictUndefined, ) template env.get_template(model.py.j2) return template.render(modelmodel) MODEL_TEMPLATE \ # generated class {{ model.name }}: {% for f in model.fields %} {{ f.name }}: {{ f.type }} {% endfor %} # end-generated if __name__ __main__: out render_model(MODEL, Path(templates)) dest Path(f{MODEL[name].lower()}.py) # 受控区块外的内容保留仅替换标记区间 dest.write_text(out, encodingutf-8) print(f已生成 {dest})真实生成器会扫描现有文件只替换generated区块。并用哈希校验元数据变更未变则不重写减少无谓 diff。四、边界分析与架构权衡生成器省事但有清晰禁区。不要生成需要判断的逻辑。业务规则、算法取舍不该模板化。生成器只适合机械、确定的部分。越界会让产物变成看不懂的黑盒。受控区块是生命线。没有隔离机制重生成会吞掉手改。必须标记生成区间且 CI 校验手改是否越界。调试难度上升。生成的代码报错栈指向产物而非模板。应保持模板可读并在产物头部注明生成来源与命令。过度生成的反模式。为未来可能用到生成一堆文件。结果仓库充斥无用代码。只生成当前真正需要的。生成器的测试策略要提前想清楚。生成代码若没有对应测试重构时无人敢改生成器本身也会随模板腐化。建议为生成器写快照测试锁定输出结构模板一变测试就红防止无意中破坏产物。另一个被忽视的点是部分生成大型模块不宜一次性全生成应按子功能增量生成并逐块 review降低单次出错面。最后生成器的输入输出要可审计每次生成依据什么元数据、产出什么文件都要留痕便于排查为什么生成了这段奇怪代码。五、总结代码生成器的本质是用元数据消除重复。机制上靠模板加受控区块实现人机协作不冲突。工程上守住在确定性产出的边界内。落地路线先识别高重复样板定义结构化元数据用模板引擎渲染以generated区块隔离手写代码CI 校验越界。把人从复制粘贴里解放出来去做真正要动脑的事。