DDD 脚手架生成工具
一个功能强大、高度可配置的领域驱动设计(DDD)项目脚手架生成工具,支持模块化单体架构。
核心特性
灵活的架构支持
- 多上下文管理:一次生成多个有界上下文(Bounded Context)
- 分层架构:支持 API、Domain、Application、Infrastructure、Interfaces 等标准 DDD 分层
- 目录结构自定义:支持标准 Maven 结构或自定义扁平结构
- 模块化命名:灵活的模块命名模式,满足不同团队规范
强大的配置能力
- 树形目录配置:直观的嵌套结构定义,所见即所得
- 文件模板系统:在配置中直接定义文件内容和模板
- 模板变量:完全可配置的变量系统,支持多层引用
- 占位符选项:自动生成
.keep、package-info.java、README 等文件
安全的回滚机制
- 文件哈希验证:基于 SHA256 哈希确保文件未被修改
- 智能跳过:自动跳过用户修改的文件,不会误删
- 父目录保护:自动保护包含用户文件的目录结构
- 清单追踪:完整记录所有生成的文件和目录
其他实用功能
- Dry-run 模式:预览生成结果,不实际创建文件
- 覆盖策略:skip、overwrite、fail 三种策略可选
- 详细日志:支持 verbose 模式,方便调试
- 向后兼容:完全兼容旧版配置格式
快速开始
安装
# 克隆仓库
git clone https://github.com/huiyiruciduojiao/scaffold_ddd.git
cd scaffold_ddd
# 无需额外依赖,Python 3.8+ 即可运行
python scaffold_ddd.py --help
初始化配置
# 生成示例配置文件
python scaffold_ddd.py --init-config scaffold.json
# 编辑配置文件
vim scaffold.json
生成项目
# 基本用法
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
回滚
# 预览回滚
python scaffold_ddd.py --rollback modules/auth/manifest.json --dry-run
# 执行回滚
python scaffold_ddd.py --rollback modules/auth/manifest.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
}
模块命名配置
{
"naming": {
"module_name_pattern": "{layer}", // 模块名模式
"context_dir_pattern": "{context}" // 上下文目录模式
}
}
示例:
{layer}→ 生成api/,domain/,application/{context}-{layer}→ 生成auth-api/,auth-domain/
占位符配置
{
"placeholders": {
"create_keep_files": true, // 为空目录创建 .keep 文件
"create_package_info": true, // 创建 package-info.java
"create_layer_readme": false, // 创建层级 README
"create_context_readme": false // 创建上下文 README
}
}
模板变量配置
{
"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)
自定义变量:支持引用其他变量,自动多轮解析
目录结构配置
方式一:树形结构(推荐)
{
"layer_dirs": {
"api": {
"contract": {},
"event": {},
"client": {},
"_files": {
"package-info.java": "package {layer_package};\n"
}
},
"domain": {
"model": {
"aggregate": {
"_files": {
".gitkeep": ""
}
},
"entity": {},
"vo": {}
},
"repository": {},
"service": {}
}
}
}
方式二:列表格式(兼容旧版)
{
"layer_dirs": {
"domain": [
"model/aggregate",
"model/entity",
"repository"
]
}
}
使用示例
示例 1: 生成单个上下文
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: 生成多个上下文
python scaffold_ddd.py \
--config scaffold.json \
--contexts auth,user,order
示例 3: 使用命令行参数覆盖配置
python scaffold_ddd.py \
--config scaffold.json \
--contexts auth \
--package-base com.mycompany.project \
--overwrite overwrite
示例 4: 预览生成结果
python scaffold_ddd.py \
--config scaffold.json \
--contexts auth \
--dry-run \
--manifest-stdout
示例 5: 安全回滚
# 1. 先预览回滚效果
python scaffold_ddd.py --rollback modules/auth/manifest.json --dry-run -v
# 2. 确认无误后执行
python scaffold_ddd.py --rollback modules/auth/manifest.json
高级功能
1. 文件模板
在配置中直接定义文件内容:
{
"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. 从外部文件读取
{
"_files": {
"README.md": {
"content_from": "templates/domain_readme.md"
}
}
}
3. 智能回滚
场景 1:所有文件未修改
$ 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:部分文件被修改
$ 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/
完整配置示例
{
"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": {}
}
}
}
命令行参数
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: 如何处理包名?
使用模板变量灵活控制:
{
"template_vars": {
"package": "{package_base}.{context}",
"layer_package": "{package}.{layer}"
}
}
在文件模板中引用:
package {layer_package}; // → top.ysit.travel.auth.domain
Q4: 可以只生成部分层吗?
可以!使用 --layers 参数:
python scaffold_ddd.py \
--config scaffold.json \
--contexts auth \
--layers api,domain
Q5: 如何在团队中共享配置?
- 将
scaffold.json提交到版本控制 - 团队成员使用相同的配置文件
- 根据项目需要在 CI/CD 中自动生成
Q6: 支持哪些编程语言?
虽然默认配置面向 Java,但通过自定义配置可以支持任何语言:
- 修改文件扩展名
- 自定义文件模板
- 调整目录结构
最佳实践
1. 版本控制策略
# 提交配置文件
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. 配置组织
{
"_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. 渐进式采用
# 步骤 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 版本
- 完整的配置文件
- 错误信息和日志
- 重现步骤
提交代码
- Fork 项目
- 创建特性分支
- 提交变更
- 创建 Pull Request
License
MIT License - 详见 LICENSE 文件
Languages
Python
100%