# DDD 脚手架生成工具 一个功能强大、高度可配置的领域驱动设计(DDD)项目脚手架生成工具,支持模块化单体架构。 ## 核心特性 ### 灵活的架构支持 - **多上下文管理**:一次生成多个有界上下文(Bounded Context) - **分层架构**:支持 API、Domain、Application、Infrastructure、Interfaces 等标准 DDD 分层 - **目录结构自定义**:支持标准 Maven 结构或自定义扁平结构 - **模块化命名**:灵活的模块命名模式,满足不同团队规范 ### 强大的配置能力 - **树形目录配置**:直观的嵌套结构定义,所见即所得 - **文件模板系统**:在配置中直接定义文件内容和模板 - **模板变量**:完全可配置的变量系统,支持多层引用 - **占位符选项**:自动生成 `.keep`、`package-info.java`、README 等文件 ### 安全的回滚机制 - **文件哈希验证**:基于 SHA256 哈希确保文件未被修改 - **智能跳过**:自动跳过用户修改的文件,不会误删 - **父目录保护**:自动保护包含用户文件的目录结构 - **清单追踪**:完整记录所有生成的文件和目录 ### 其他实用功能 - **Dry-run 模式**:预览生成结果,不实际创建文件 - **覆盖策略**:skip、overwrite、fail 三种策略可选 - **详细日志**:支持 verbose 模式,方便调试 - **向后兼容**:完全兼容旧版配置格式 --- ## 快速开始 ### 安装 ```bash # 克隆仓库 git clone cd # 无需额外依赖,Python 3.8+ 即可运行 python scaffold_ddd.py --help ``` ### 初始化配置 ```bash # 生成示例配置文件 python scaffold_ddd.py --init-config scaffold.json # 编辑配置文件 vim scaffold.json ``` ### 生成项目 ```bash # 基本用法 python scaffold_ddd.py --config scaffold.json --contexts auth,user # 预览模式(不实际创建文件) python scaffold_ddd.py --config scaffold.json --contexts auth --dry-run # 详细日志 python scaffold_ddd.py --config scaffold.json --contexts auth -v ``` ### 回滚 ```bash # 预览回滚 python scaffold_ddd.py --rollback modules/auth/manifest.json --dry-run # 执行回滚 python scaffold_ddd.py --rollback modules/auth/manifest.json ``` --- ## 配置文件详解 ### 基本配置 ```json { "root": "modules", // 上下文根目录 "package_base": "top.ysit.travel", // 基础包名 "contexts": ["auth", "user"], // 要生成的上下文列表 "layers": [ // 要生成的层 "api", "domain", "application", "infrastructure", "interfaces" ], "use_standard_structure": false, // 是否使用标准 Maven 结构 "overwrite": "skip" // 覆盖策略:skip | overwrite | fail } ``` ### 模块命名配置 ```json { "naming": { "module_name_pattern": "{layer}", // 模块名模式 "context_dir_pattern": "{context}" // 上下文目录模式 } } ``` **示例**: - `{layer}` → 生成 `api/`, `domain/`, `application/` - `{context}-{layer}` → 生成 `auth-api/`, `auth-domain/` ### 占位符配置 ```json { "placeholders": { "create_keep_files": true, // 为空目录创建 .keep 文件 "create_package_info": true, // 创建 package-info.java "create_layer_readme": false, // 创建层级 README "create_context_readme": false // 创建上下文 README } } ``` ### 模板变量配置 ```json { "template_vars": { "package": "{package_base}.{context}", "context_package": "{package_base}.{context}", "layer_package": "{package}.{layer}", "author": "Your Name", "organization": "Your Org" } } ``` **内置变量**: - `{context}` - 上下文名称(如 `auth`) - `{layer}` - 层名称(如 `domain`) - `{module}` - 模块名称(如 `auth-domain`) - `{package_base}` - 基础包名(如 `top.ysit.travel`) **自定义变量**:支持引用其他变量,自动多轮解析 ### 目录结构配置 #### 方式一:树形结构(推荐) ```json { "layer_dirs": { "api": { "contract": {}, "event": {}, "client": {}, "_files": { "package-info.java": "package {layer_package};\n" } }, "domain": { "model": { "aggregate": { "_files": { ".gitkeep": "" } }, "entity": {}, "vo": {} }, "repository": {}, "service": {} } } } ``` #### 方式二:列表格式(兼容旧版) ```json { "layer_dirs": { "domain": [ "model/aggregate", "model/entity", "repository" ] } } ``` --- ## 使用示例 ### 示例 1: 生成单个上下文 ```bash python scaffold_ddd.py \ --config scaffold.json \ --contexts auth ``` **生成结构**: ``` modules/ └── auth/ ├── manifest.json ├── api/ │ ├── package-info.java │ ├── contract/ │ ├── event/ │ └── client/ ├── domain/ │ ├── package-info.java │ ├── model/ │ │ ├── aggregate/ │ │ ├── entity/ │ │ └── vo/ │ ├── repository/ │ └── service/ └── ... ``` ### 示例 2: 生成多个上下文 ```bash python scaffold_ddd.py \ --config scaffold.json \ --contexts auth,user,order ``` ### 示例 3: 使用命令行参数覆盖配置 ```bash python scaffold_ddd.py \ --config scaffold.json \ --contexts auth \ --package-base com.mycompany.project \ --overwrite overwrite ``` ### 示例 4: 预览生成结果 ```bash python scaffold_ddd.py \ --config scaffold.json \ --contexts auth \ --dry-run \ --manifest-stdout ``` ### 示例 5: 安全回滚 ```bash # 1. 先预览回滚效果 python scaffold_ddd.py --rollback modules/auth/manifest.json --dry-run -v # 2. 确认无误后执行 python scaffold_ddd.py --rollback modules/auth/manifest.json ``` --- ## 高级功能 ### 1. 文件模板 在配置中直接定义文件内容: ```json { "layer_dirs": { "domain": { "exception": { "_files": { "DomainException.java": "package {context_package}.domain.exception;\n\n/**\n * Base domain exception for {context} context\n * @author {author}\n */\npublic class DomainException extends RuntimeException {\n public DomainException(String message) {\n super(message);\n }\n}\n" } } } } } ``` ### 2. 从外部文件读取 ```json { "_files": { "README.md": { "content_from": "templates/domain_readme.md" } } } ``` ### 3. 智能回滚 **场景 1**:所有文件未修改 ```bash $ python scaffold_ddd.py --rollback modules/auth/manifest.json INFO ✓ Verified 34 file(s) by hash INFO Deleted 35 file(s) INFO Deleted empty context directory: modules\auth INFO Rollback completed successfully ``` **场景 2**:部分文件被修改 ```bash $ python scaffold_ddd.py --rollback modules/auth/manifest.json WARNING ⚠ Hash verification failed for 2 file(s). These files will be skipped. WARNING - modules\auth\api\README.md INFO Deleted 32 file(s) INFO Protected 5 path(s) due to skipped files WARNING ⚠ Rollback completed with 2 file(s) skipped ``` ### 4. 自定义包结构 **标准结构**(`use_standard_structure: true`): ``` modules/auth/domain/ └── src/main/java/ └── top/ysit/travel/auth/domain/ ├── model/ └── repository/ ``` **扁平结构**(`use_standard_structure: false`): ``` modules/auth/domain/ ├── model/ └── repository/ ``` --- ## 完整配置示例 ```json { "root": "modules", "package_base": "top.ysit.travel", "contexts": ["auth", "user", "order"], "layers": ["api", "domain", "application", "infrastructure", "interfaces"], "java_source_dir": "src/main/java", "resources_dir": "src/main/resources", "overwrite": "skip", "dry_run": false, "emit_manifest": true, "manifest_name": "manifest.json", "use_standard_structure": false, "naming": { "module_name_pattern": "{layer}", "context_dir_pattern": "{context}" }, "placeholders": { "create_keep_files": true, "create_package_info": true, "create_layer_readme": false, "create_context_readme": false }, "template_vars": { "package": "{package_base}.{context}", "context_package": "{package_base}.{context}", "layer_package": "{package}.{layer}", "author": "DDD Scaffold Tool", "organization": "YSIT", "license": "MIT" }, "layer_dirs": { "api": { "contract": {}, "event": {}, "client": {}, "_files": { "package-info.java": "/**\n * API contracts for {context} context.\n * @author {author}\n */\npackage {layer_package};\n" } }, "domain": { "model": { "aggregate": { "_files": { ".gitkeep": "" } }, "entity": {}, "vo": {}, "enum": {} }, "repository": {}, "event": {}, "service": {}, "exception": { "_files": { "DomainException.java": "package {context_package}.domain.exception;\n\npublic class DomainException extends RuntimeException {\n public DomainException(String message) {\n super(message);\n }\n}\n" } } }, "application": { "command": {}, "usecase": {}, "query": { "dto": {} }, "assembler": {}, "port": { "in": {}, "out": {} }, "security": {}, "handler": {} }, "infrastructure": { "persistence": { "mapper": {}, "po": {}, "convert": {}, "repository": {} }, "event": {}, "config": {} }, "interfaces": { "web": { "request": {}, "response": {} }, "facade": {}, "doc": {} } } } ``` --- ## 命令行参数 ```bash python scaffold_ddd.py [OPTIONS] Options: --config PATH 配置文件路径 --init-config PATH 生成示例配置文件 --root DIR 上下文根目录(覆盖配置) --package-base PKG 基础包名(覆盖配置) --contexts CONTEXTS 逗号分隔的上下文列表 --layers LAYERS 逗号分隔的层列表 --overwrite POLICY 覆盖策略:skip | overwrite | fail --dry-run 预览模式,不创建文件 --no-manifest 不生成 manifest.json --manifest-stdout 输出 manifest 到标准输出 --manifest-write-in-dry-run 在 dry-run 模式也写入 manifest --rollback MANIFEST_PATH 使用指定 manifest 回滚 -v, --verbose 详细日志输出 --help 显示帮助信息 ``` --- ## 常见问题 ### Q1: 如何选择目录结构? **标准 Maven 结构** (`use_standard_structure: true`): - 适合传统 Maven/Gradle 项目 - IDE 友好,自动识别源码目录 - 目录层级较深 **扁平结构** (`use_standard_structure: false`): - 目录结构简洁 - 适合模块化单体架构 - 需要手动配置 IDE 源码目录 ### Q2: 回滚会删除我修改的文件吗? **不会!** 回滚功能使用 SHA256 哈希验证: - 自动跳过被修改的文件 - 保护包含被修改文件的父目录 - 详细日志显示被跳过的文件 ### Q3: 如何处理包名? 使用模板变量灵活控制: ```json { "template_vars": { "package": "{package_base}.{context}", "layer_package": "{package}.{layer}" } } ``` 在文件模板中引用: ```java package {layer_package}; // → top.ysit.travel.auth.domain ``` ### Q4: 可以只生成部分层吗? 可以!使用 `--layers` 参数: ```bash python scaffold_ddd.py \ --config scaffold.json \ --contexts auth \ --layers api,domain ``` ### Q5: 如何在团队中共享配置? 1. 将 `scaffold.json` 提交到版本控制 2. 团队成员使用相同的配置文件 3. 根据项目需要在 CI/CD 中自动生成 ### Q6: 支持哪些编程语言? 虽然默认配置面向 Java,但通过自定义配置可以支持任何语言: - 修改文件扩展名 - 自定义文件模板 - 调整目录结构 --- ## 最佳实践 ### 1. 版本控制策略 ```bash # 提交配置文件 git add scaffold.json scaffold_ddd.py git commit -m "Add DDD scaffold configuration" # 不要提交生成的代码到主分支 echo "modules/" >> .gitignore # 或者只提交初始骨架,后续开发不提交 git add modules/auth/domain/model/ git commit -m "Add domain model skeleton" ``` ### 2. 配置组织 ```json { "_comment": { "description": "Auth context scaffold configuration", "author": "Team Name", "last_updated": "2026-01-11" }, "template_vars": { "_comment": "Package naming conventions", "package": "{package_base}.{context}", ... } } ``` ### 3. 渐进式采用 ```bash # 步骤 1: 预览效果 python scaffold_ddd.py --config scaffold.json --contexts auth --dry-run # 步骤 2: 生成一个上下文测试 python scaffold_ddd.py --config scaffold.json --contexts auth # 步骤 3: 确认无误后生成所有上下文 python scaffold_ddd.py --config scaffold.json ``` ### 4. 模板复用 将常用文件模板提取到外部: ``` templates/ ├── domain_exception.java ├── package-info.java └── README.md scaffold.json: { "_files": { "DomainException.java": { "content_from": "templates/domain_exception.java" } } } ``` --- ## 贡献指南 欢迎提交 Issue 和 Pull Request! ### 报告问题 提交 Issue 时请包含: - Python 版本 - 完整的配置文件 - 错误信息和日志 - 重现步骤 ### 提交代码 1. Fork 项目 2. 创建特性分支 3. 提交变更 4. 创建 Pull Request --- ## License MIT License - 详见 [LICENSE](LICENSE) 文件